Adafruit 64x32 RGB LED Matrix - 3mm pitch driver for Nucleo-F446RE

Dependents:   RGB_Matrix_Test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RGB_Matrix.cpp Source File

RGB_Matrix.cpp

00001 /* mbed RGB Matrix Library
00002  * Written for Nucleo-F446RE, v1.0, 03-10-2015
00003  *
00004  * Copyright (c) 2013-2015 JackB, cstyles
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a copy
00007  * of this software and associated documentation files (the "Software"), to deal
00008  * in the Software without restriction, including without limitation the rights
00009  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010  * copies of the Software, and to permit persons to whom the Software is
00011  * furnished to do so, subject to the following conditions:
00012  *
00013  * The above copyright notice and this permission notice shall be included in
00014  * all copies or substantial portions of the Software.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00019  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00020  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00021  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00022  * THE SOFTWARE.
00023  */
00024 
00025 #include "RGB_Matrix.h"
00026 
00027 RGB_Matrix::RGB_Matrix(PinName Pin_R1, PinName Pin_R2,
00028                        PinName Pin_G1, PinName Pin_G2,
00029                        PinName Pin_B1, PinName Pin_B2,
00030                        PinName Pin_CLK, PinName Pin_LAT, PinName Pin_OE,
00031                        PinName Pin_A, PinName Pin_B, PinName Pin_C, PinName Pin_D) :
00032     _Pin_R1(Pin_R1), _Pin_R2(Pin_R2),
00033     _Pin_G1(Pin_G1), _Pin_G2(Pin_G2),
00034     _Pin_B1(Pin_B1), _Pin_B2(Pin_B2),
00035     _Pin_CLK(Pin_CLK), _Pin_LAT(Pin_LAT), _Pin_OE(Pin_OE),
00036     _Pin_A(Pin_A), _Pin_B(Pin_B), _Pin_C(Pin_C), _Pin_D(Pin_D) {
00037 }
00038 
00039 void RGB_Matrix::Init(void) {
00040 //    uint8_t *ptr;
00041 
00042     _Pin_CLK = 0; // Clock low
00043     _Pin_OE  = 1; // Disable LED output during row/plane switchover
00044     _Pin_LAT = 1; // Latch data loaded during *prior* interrupt
00045 
00046     plane     = PLANES - 1;
00047     row       = ROWS   - 1;
00048 
00049     // Allocate and initialize matrix buffer:
00050 
00051     int buffsize  = WIDTH * ROWS * PLANES,
00052         allocsize = (DBUF == true) ? (buffsize * 2) : buffsize;
00053 
00054     if(NULL == (matrixbuff[0] = (uint8_t *)malloc(allocsize)))
00055         return;
00056     memset(matrixbuff[0], 0, allocsize);
00057 
00058     if(NULL == (matrixbuff[1] = (uint8_t *)malloc(allocsize)))
00059         return;
00060     memset(matrixbuff[1], 0, allocsize);
00061 
00062     // If not double-buffered, both buffers then point to the same address:
00063 //    matrixbuff[1] = (DBUF == true) ? &matrixbuff[0][buffsize] : matrixbuff[0];
00064 
00065     bufferDisplay = 0;
00066     bufferWrite   = 0;
00067 //    buffptr       = matrixbuff[bufferDisplay]; // -> front buffer
00068 
00069     /*
00070         // Some data!
00071         buffptr[0] = 0x11;
00072         buffptr[1] = 0x22;
00073         buffptr[2] = 0x44;
00074         buffptr[0+PIXELS] = 0x11;
00075         buffptr[1+PIXELS] = 0x22;
00076         buffptr[2+PIXELS] = 0x44;
00077         buffptr[0+PIXELS*2] = 0x11;
00078         buffptr[1+PIXELS*2] = 0x22;
00079         buffptr[2+PIXELS*2] = 0x44;
00080         buffptr[0+PIXELS*3] = 0x11;
00081         buffptr[1+PIXELS*3] = 0x22;
00082         buffptr[2+PIXELS*3] = 0x44;
00083         buffptr[0+PIXELS*4] = 0x11;
00084         buffptr[1+PIXELS*4] = 0x22;
00085         buffptr[2+PIXELS*4] = 0x44;
00086         buffptr[0+PIXELS*5] = 0x11;
00087         buffptr[1+PIXELS*5] = 0x22;
00088         buffptr[2+PIXELS*5] = 0x44;
00089         buffptr[0+PIXELS*6] = 0x11;
00090         buffptr[1+PIXELS*6] = 0x22;
00091         buffptr[2+PIXELS*6] = 0x44;
00092 
00093         buffptr[0+WIDTH] = 0x00;
00094         buffptr[1+WIDTH] = 0x00;
00095         buffptr[2+WIDTH] = 0x00;
00096         buffptr[0+WIDTH+PIXELS] = 0x11;
00097         buffptr[1+WIDTH+PIXELS] = 0x22;
00098         buffptr[2+WIDTH+PIXELS] = 0x44;
00099         buffptr[0+WIDTH+PIXELS*2] = 0x11;
00100         buffptr[1+WIDTH+PIXELS*2] = 0x22;
00101         buffptr[2+WIDTH+PIXELS*2] = 0x44;
00102         buffptr[0+WIDTH+PIXELS*3] = 0x11;
00103         buffptr[1+WIDTH+PIXELS*3] = 0x22;
00104         buffptr[2+WIDTH+PIXELS*3] = 0x44;
00105         buffptr[0+WIDTH+PIXELS*4] = 0x11;
00106         buffptr[1+WIDTH+PIXELS*4] = 0x22;
00107         buffptr[2+WIDTH+PIXELS*4] = 0x44;
00108         buffptr[0+WIDTH+PIXELS*5] = 0x11;
00109         buffptr[1+WIDTH+PIXELS*5] = 0x22;
00110         buffptr[2+WIDTH+PIXELS*5] = 0x44;
00111         buffptr[0+WIDTH+PIXELS*6] = 0x11;
00112         buffptr[1+WIDTH+PIXELS*6] = 0x22;
00113         buffptr[2+WIDTH+PIXELS*6] = 0x44;
00114 
00115         buffptr[0+WIDTH*2] = 0x00;
00116         buffptr[1+WIDTH*2] = 0x00;
00117         buffptr[2+WIDTH*2] = 0x00;
00118         buffptr[0+WIDTH*2+PIXELS] = 0x00;
00119         buffptr[1+WIDTH*2+PIXELS] = 0x00;
00120         buffptr[2+WIDTH*2+PIXELS] = 0x00;
00121         buffptr[0+WIDTH*2+PIXELS*2] = 0x11;
00122         buffptr[1+WIDTH*2+PIXELS*2] = 0x22;
00123         buffptr[2+WIDTH*2+PIXELS*2] = 0x44;
00124         buffptr[0+WIDTH*2+PIXELS*3] = 0x11;
00125         buffptr[1+WIDTH*2+PIXELS*3] = 0x22;
00126         buffptr[2+WIDTH*2+PIXELS*3] = 0x44;
00127         buffptr[0+WIDTH*2+PIXELS*4] = 0x11;
00128         buffptr[1+WIDTH*2+PIXELS*4] = 0x22;
00129         buffptr[2+WIDTH*2+PIXELS*4] = 0x44;
00130         buffptr[0+WIDTH*2+PIXELS*5] = 0x11;
00131         buffptr[1+WIDTH*2+PIXELS*5] = 0x22;
00132         buffptr[2+WIDTH*2+PIXELS*5] = 0x44;
00133         buffptr[0+WIDTH*2+PIXELS*6] = 0x11;
00134         buffptr[1+WIDTH*2+PIXELS*6] = 0x22;
00135         buffptr[2+WIDTH*2+PIXELS*6] = 0x44;
00136 
00137         buffptr[0+WIDTH*3] = 0x00;
00138         buffptr[1+WIDTH*3] = 0x00;
00139         buffptr[2+WIDTH*3] = 0x00;
00140         buffptr[0+WIDTH*3+PIXELS] = 0x00;
00141         buffptr[1+WIDTH*3+PIXELS] = 0x00;
00142         buffptr[2+WIDTH*3+PIXELS] = 0x00;
00143         buffptr[0+WIDTH*3+PIXELS*2] = 0x00;
00144         buffptr[1+WIDTH*3+PIXELS*2] = 0x00;
00145         buffptr[2+WIDTH*3+PIXELS*2] = 0x00;
00146         buffptr[0+WIDTH*3+PIXELS*3] = 0x11;
00147         buffptr[1+WIDTH*3+PIXELS*3] = 0x22;
00148         buffptr[2+WIDTH*3+PIXELS*3] = 0x44;
00149         buffptr[0+WIDTH*3+PIXELS*4] = 0x11;
00150         buffptr[1+WIDTH*3+PIXELS*4] = 0x22;
00151         buffptr[2+WIDTH*3+PIXELS*4] = 0x44;
00152         buffptr[0+WIDTH*3+PIXELS*5] = 0x11;
00153         buffptr[1+WIDTH*3+PIXELS*5] = 0x22;
00154         buffptr[2+WIDTH*3+PIXELS*5] = 0x44;
00155         buffptr[0+WIDTH*3+PIXELS*6] = 0x11;
00156         buffptr[1+WIDTH*3+PIXELS*6] = 0x22;
00157         buffptr[2+WIDTH*3+PIXELS*6] = 0x44;
00158 
00159         buffptr[0+WIDTH*4] = 0x00;
00160         buffptr[1+WIDTH*4] = 0x00;
00161         buffptr[2+WIDTH*4] = 0x00;
00162         buffptr[0+WIDTH*4+PIXELS] = 0x00;
00163         buffptr[1+WIDTH*4+PIXELS] = 0x00;
00164         buffptr[2+WIDTH*4+PIXELS] = 0x00;
00165         buffptr[0+WIDTH*4+PIXELS*2] = 0x00;
00166         buffptr[1+WIDTH*4+PIXELS*2] = 0x00;
00167         buffptr[2+WIDTH*4+PIXELS*2] = 0x00;
00168         buffptr[0+WIDTH*4+PIXELS*3] = 0x00;
00169         buffptr[1+WIDTH*4+PIXELS*3] = 0x00;
00170         buffptr[2+WIDTH*4+PIXELS*3] = 0x00;
00171         buffptr[0+WIDTH*4+PIXELS*4] = 0x11;
00172         buffptr[1+WIDTH*4+PIXELS*4] = 0x22;
00173         buffptr[2+WIDTH*4+PIXELS*4] = 0x44;
00174         buffptr[0+WIDTH*4+PIXELS*5] = 0x11;
00175         buffptr[1+WIDTH*4+PIXELS*5] = 0x22;
00176         buffptr[2+WIDTH*4+PIXELS*5] = 0x44;
00177         buffptr[0+WIDTH*4+PIXELS*6] = 0x11;
00178         buffptr[1+WIDTH*4+PIXELS*6] = 0x22;
00179         buffptr[2+WIDTH*4+PIXELS*6] = 0x44;
00180 
00181         buffptr[0+WIDTH*5] = 0x00;
00182         buffptr[1+WIDTH*5] = 0x00;
00183         buffptr[2+WIDTH*5] = 0x00;
00184         buffptr[0+WIDTH*5+PIXELS] = 0x00;
00185         buffptr[1+WIDTH*5+PIXELS] = 0x00;
00186         buffptr[2+WIDTH*5+PIXELS] = 0x00;
00187         buffptr[0+WIDTH*5+PIXELS*2] = 0x00;
00188         buffptr[1+WIDTH*5+PIXELS*2] = 0x00;
00189         buffptr[2+WIDTH*5+PIXELS*2] = 0x00;
00190         buffptr[0+WIDTH*5+PIXELS*3] = 0x00;
00191         buffptr[1+WIDTH*5+PIXELS*3] = 0x00;
00192         buffptr[2+WIDTH*5+PIXELS*3] = 0x00;
00193         buffptr[0+WIDTH*5+PIXELS*4] = 0x00;
00194         buffptr[1+WIDTH*5+PIXELS*4] = 0x00;
00195         buffptr[2+WIDTH*5+PIXELS*4] = 0x00;
00196         buffptr[0+WIDTH*5+PIXELS*5] = 0x11;
00197         buffptr[1+WIDTH*5+PIXELS*5] = 0x22;
00198         buffptr[2+WIDTH*5+PIXELS*5] = 0x44;
00199         buffptr[0+WIDTH*5+PIXELS*6] = 0x11;
00200         buffptr[1+WIDTH*5+PIXELS*6] = 0x22;
00201         buffptr[2+WIDTH*5+PIXELS*6] = 0x44;
00202 
00203         buffptr[0+WIDTH*6] = 0x00;
00204         buffptr[1+WIDTH*6] = 0x00;
00205         buffptr[2+WIDTH*6] = 0x00;
00206         buffptr[0+WIDTH*6+PIXELS] = 0x00;
00207         buffptr[1+WIDTH*6+PIXELS] = 0x00;
00208         buffptr[2+WIDTH*6+PIXELS] = 0x00;
00209         buffptr[0+WIDTH*6+PIXELS*2] = 0x00;
00210         buffptr[1+WIDTH*6+PIXELS*2] = 0x00;
00211         buffptr[2+WIDTH*6+PIXELS*2] = 0x00;
00212         buffptr[0+WIDTH*6+PIXELS*3] = 0x00;
00213         buffptr[1+WIDTH*6+PIXELS*3] = 0x00;
00214         buffptr[2+WIDTH*6+PIXELS*3] = 0x00;
00215         buffptr[0+WIDTH*6+PIXELS*4] = 0x00;
00216         buffptr[1+WIDTH*6+PIXELS*4] = 0x00;
00217         buffptr[2+WIDTH*6+PIXELS*4] = 0x00;
00218         buffptr[0+WIDTH*6+PIXELS*5] = 0x00;
00219         buffptr[1+WIDTH*6+PIXELS*5] = 0x00;
00220         buffptr[2+WIDTH*6+PIXELS*5] = 0x00;
00221         buffptr[0+WIDTH*6+PIXELS*6] = 0x11;
00222         buffptr[1+WIDTH*6+PIXELS*6] = 0x22;
00223         buffptr[2+WIDTH*6+PIXELS*6] = 0x44;
00224     */
00225     /*
00226         buffptr[1] = 0x02;
00227         buffptr[2] = 0x03;
00228         buffptr[3] = 0x04;
00229         buffptr[4] = 0x08;
00230         buffptr[5] = 0x0c;
00231         buffptr[6] = 0x10;
00232         buffptr[7] = 0x20;
00233         buffptr[8] = 0x30;
00234         buffptr[WIDTH*ROWS+3] = 0x01;
00235         buffptr[WIDTH*ROWS+4] = 0x04;
00236         buffptr[WIDTH*ROWS+5] = 0x10;
00237 
00238         drawPixel(2, 4, RGB(255, 128, 0)); // RRrrrGGg gggBBbbb
00239     */
00240 
00241     Update.attach(this, &RGB_Matrix::updateDisplay, INTTIME); // the address of the function to be attached (flip) and the interval (0.5 seconds)
00242     char_x = 0;
00243     char_y = 0;
00244     foreground(RGB(0, 64, 0));
00245     background(RGB(0, 0, 0));
00246     SetOrientation(LANDSCAPE_B);
00247 }
00248 
00249 void RGB_Matrix::swap(int16_t &x, int16_t &y) {
00250     int16_t temp = x;
00251     x = y;
00252     y = temp;
00253 }
00254 
00255 uint16_t RGB_Matrix::rgbToColor(uint8_t R, uint8_t G, uint8_t  B) {
00256     return ((R >> 6) << 14) + ((G >> 6) << 9) + ((B >> 6) << 3); // RRrrrGGg gggBBbbb
00257 }
00258 
00259 void RGB_Matrix::drawPixel2(int16_t x, int16_t y, uint16_t c) {
00260     uint8_t r, g, b, bit, limit, *ptr;
00261 
00262     if((x < 0) || (x >= WIDTH) || (y < 0) || (y >= HEIGHT))
00263         return;
00264 
00265     switch(_orientation) {
00266         case 1:
00267             swap(x, y);
00268             x = WIDTH  - 1 - x;
00269             break;
00270         case 2:
00271             x = WIDTH  - 1 - x;
00272             y = HEIGHT - 1 - y;
00273             break;
00274         case 3:
00275             swap(x, y);
00276             y = HEIGHT - 1 - y;
00277             break;
00278     }
00279 
00280     // Adafruit_GFX uses 16-bit color in 5/6/5 format, while matrix needs
00281     // 2/2/2.  Pluck out relevant bits while separating into R,G,B:
00282     r =  c >> 14;        // RRrrrggggggbbbbb
00283     g = (c >>  9) & 0x03; // rrrrrGGggggbbbbb
00284     b = (c >>  3) & 0x03; // rrrrrggggggBBbbb
00285 
00286     uint8_t color = r + (g << 2) + (b << 4);
00287 
00288     buffptr = matrixbuff[bufferWrite]; // Set first buffer
00289     buffptr[y * WIDTH + x] = color;
00290 }
00291 
00292 void RGB_Matrix::drawPixel(int16_t x, int16_t y, uint16_t c) {
00293     uint8_t r, g, b, bit, limit, *ptr;
00294 
00295     if((x < 0) || (x >= WIDTH) || (y < 0) || (y >= HEIGHT))
00296         return;
00297 
00298     switch(_orientation) {
00299         case 1:
00300             swap(x, y);
00301             x = WIDTH  - 1 - x;
00302             break;
00303         case 2:
00304             x = WIDTH  - 1 - x;
00305             y = HEIGHT - 1 - y;
00306             break;
00307         case 3:
00308             swap(x, y);
00309             y = HEIGHT - 1 - y;
00310             break;
00311     }
00312 
00313     // Adafruit_GFX uses 16-bit color in 5/6/5 format, while matrix needs
00314     // 2/2/2.  Pluck out relevant bits while separating into R,G,B:
00315     r =  c >> 13;         // RRRrrggggggbbbbb
00316     g = (c >>  8) & 0x07; // rrrrrGGGgggbbbbb
00317     b = (c >>  2) & 0x07; // rrrrrggggggBBBbb
00318 
00319     uint8_t color = r + (g << 2) + (b << 4);
00320 
00321 
00322     uint8_t *buffptr;
00323     buffptr = matrixbuff[bufferWrite]; // Set first buffer
00324 
00325     const uint8_t PixelR1[] = {
00326         0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
00327         0xfe, 0xfe, 0xfe, 0x01, 0xfe, 0xfe, 0xfe,
00328         0xfe, 0x01, 0xfe, 0xfe, 0xfe, 0x01, 0xfe,
00329         0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe,
00330         0x01, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe,
00331         0x01, 0x01, 0x01, 0xfe, 0x01, 0x01, 0xfe,
00332         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xfe,
00333         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
00334     };
00335 
00336     const uint8_t PixelR2[] = {
00337         0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
00338         0xef, 0xef, 0xef, 0x10, 0xef, 0xef, 0xef,
00339         0xef, 0x10, 0xef, 0xef, 0xef, 0x10, 0xef,
00340         0xef, 0x10, 0xef, 0x10, 0xef, 0x10, 0xef,
00341         0x10, 0x10, 0xef, 0x10, 0xef, 0x10, 0xef,
00342         0x10, 0x10, 0x10, 0xef, 0x10, 0x10, 0xef,
00343         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xef,
00344         0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
00345     };
00346 
00347     const uint8_t PixelG1[] = {
00348         0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
00349         0xfd, 0xfd, 0xfd, 0x02, 0xfd, 0xfd, 0xfd,
00350         0xfd, 0x02, 0xfd, 0xfd, 0xfd, 0x02, 0xfd,
00351         0xfd, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd,
00352         0x02, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0xfd,
00353         0x02, 0x02, 0x02, 0xfd, 0x02, 0x02, 0xfd,
00354         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0xfd,
00355         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
00356     };
00357 
00358     const uint8_t PixelG2[] = {
00359         0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
00360         0xdf, 0xdf, 0xdf, 0x20, 0xdf, 0xdf, 0xdf,
00361         0xdf, 0x20, 0xdf, 0xdf, 0xdf, 0x20, 0xdf,
00362         0xdf, 0x20, 0xdf, 0x20, 0xdf, 0x20, 0xdf,
00363         0x20, 0x20, 0xdf, 0x20, 0xdf, 0x20, 0xdf,
00364         0x20, 0x20, 0x20, 0xdf, 0x20, 0x20, 0xdf,
00365         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xdf,
00366         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
00367     };
00368 
00369     const uint8_t PixelB1[] = {
00370         0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
00371         0xfb, 0xfb, 0xfb, 0x04, 0xfb, 0xfb, 0xfb,
00372         0xfb, 0x04, 0xfb, 0xfb, 0xfb, 0x04, 0xfb,
00373         0xfb, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb,
00374         0x04, 0x04, 0xfb, 0x04, 0xfb, 0x04, 0xfb,
00375         0x04, 0x04, 0x04, 0xfb, 0x04, 0x04, 0xfb,
00376         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xfb,
00377         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04
00378     };
00379 
00380     const uint8_t PixelB2[] = {
00381         0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
00382         0xbf, 0xbf, 0xbf, 0x40, 0xbf, 0xbf, 0xbf,
00383         0xbf, 0x40, 0xbf, 0xbf, 0xbf, 0x40, 0xbf,
00384         0xbf, 0x40, 0xbf, 0x40, 0xbf, 0x40, 0xbf,
00385         0x40, 0x40, 0xbf, 0x40, 0xbf, 0x40, 0xbf,
00386         0x40, 0x40, 0x40, 0xbf, 0x40, 0x40, 0xbf,
00387         0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xbf,
00388         0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
00389     };
00390 
00391     // PWM planes
00392     // xBGRxBGR
00393 
00394     for (uint8_t p = 0; p < PLANES; p++) {
00395         if (y < ROWS) {
00396             if ((PixelR1[p+r*7] & 0x80) == 0)
00397                 buffptr[x+WIDTH*y+PIXELS*p] |= PixelR1[p+r*7];
00398             else
00399                 buffptr[x+WIDTH*y+PIXELS*p] &= PixelR1[p+r*7];
00400             if ((PixelG1[p+g*7] & 0x80) == 0)
00401                 buffptr[x+WIDTH*y+PIXELS*p] |= PixelG1[p+g*7];
00402             else
00403                 buffptr[x+WIDTH*y+PIXELS*p] &= PixelG1[p+g*7];
00404             if ((PixelB1[p+b*7] & 0x80) == 0)
00405                 buffptr[x+WIDTH*y+PIXELS*p] |= PixelB1[p+b*7];
00406             else
00407                 buffptr[x+WIDTH*y+PIXELS*p] &= PixelB1[p+b*7];
00408         } else {
00409             if ((PixelR2[p+r*7] & 0x80) == 0)
00410                 buffptr[x+WIDTH*(y-ROWS)+PIXELS*p] |= PixelR2[p+r*7];
00411             else
00412                 buffptr[x+WIDTH*(y-ROWS)+PIXELS*p] &= PixelR2[p+r*7];
00413             if ((PixelG2[p+g*7] & 0x80) == 0)
00414                 buffptr[x+WIDTH*(y-ROWS)+PIXELS*p] |= PixelG2[p+g*7];
00415             else
00416                 buffptr[x+WIDTH*(y-ROWS)+PIXELS*p] &= PixelG2[p+g*7];
00417             if ((PixelB2[p+b*7] & 0x80) == 0)
00418                 buffptr[x+WIDTH*(y-ROWS)+PIXELS*p] |= PixelB2[p+b*7];
00419             else
00420                 buffptr[x+WIDTH*(y-ROWS)+PIXELS*p] &= PixelB2[p+b*7];
00421         }
00422     }
00423 }
00424 
00425 void RGB_Matrix::set_font(unsigned char* f) {
00426     font = f;
00427 }
00428 
00429 void RGB_Matrix::character(int x, int y, int c) {
00430     unsigned int hor,vert,offset,bpl,j,i,b;
00431     unsigned char* char_offset;
00432     unsigned char z,w;
00433 
00434     if ((c < 31) || (c > 127)) return;   // test char range
00435 
00436     // read font parameter from start of array
00437     offset = font[BYTESPERCHAR];                    // bytes / char
00438     hor    = font[FONTWIDTH];                       // get hor size of font
00439     vert   = font[FONTHEIGHT];                      // get vert size of font
00440     bpl    = font[BYTESPERLINE];                    // bytes per vertical line
00441 
00442     if (char_x + hor > width()) {
00443         // the next character doesn't fit on the same line
00444         char_x = 0;
00445         char_y = char_y + vert;
00446         if (char_y > height() - font[FONTHEIGHT]) {
00447             // the next line doesn't fit at the bottom of the screen
00448             char_y = 0;
00449         }
00450     }
00451 
00452 //    window(char_x, char_y,hor,vert); // char box
00453 
00454     char_offset = &font[((c -32) * offset) + 4]; // start of char bitmap
00455     w = char_offset[0];                          // width of actual char
00456     for (j=0; j<vert; j++) {  //  vert line
00457         for (i=0; i<hor; i++) {   //  horz line
00458             z =  char_offset[bpl * i + ((j & 0xF8) >> 3)+1];
00459             b = 1 << (j & 0x07);
00460             if (( z & b ) == 0x00) {
00461                 drawPixel(char_x + i, char_y + j, _background); // background
00462             } else {
00463                 drawPixel(char_x + i, char_y + j, _foreground); // foreground
00464             }
00465         }
00466     }
00467 //    WindowMax();
00468     if ((w + 2) < hor) {                   // x offset to next char
00469         char_x += w + 2;
00470     } else char_x += hor;
00471 }
00472 
00473 int RGB_Matrix::putc(int value) {
00474     if (value == '\n') {    // new line
00475         char_x = 0;
00476         char_y = char_y + font[FONTHEIGHT];
00477         if (char_y >= height() - font[FONTHEIGHT]) {
00478             char_y = 0;
00479         }
00480     } else {
00481         character(char_x, char_y, value);
00482     }
00483     return value;
00484 }
00485 
00486 void RGB_Matrix::printString(char *string) {
00487     for (uint8_t i = 0; i < strlen(string); i++) {
00488         putc(string[i]);
00489     }
00490 }
00491 
00492 void RGB_Matrix::printStringCenter(char *string) {
00493     uint8_t pwidth = strlen(string) * font[FONTWIDTH] - 1;
00494     locatePixelX((width() - pwidth) / 2);
00495     for (uint8_t i = 0; i < strlen(string); i++) {
00496         putc(string[i]);
00497     }
00498 }
00499 
00500 void RGB_Matrix::foreground(uint16_t colour) {
00501     _foreground = colour;
00502 }
00503 
00504 void RGB_Matrix::background(uint16_t colour) {
00505     _background = colour;
00506 }
00507 
00508 int RGB_Matrix::width() {
00509     if (_orientation == 0 || _orientation == 2) return WIDTH;
00510     else return HEIGHT;
00511 }
00512 
00513 int RGB_Matrix::height() {
00514     if (_orientation == 0 || _orientation == 2) return HEIGHT;
00515     else return WIDTH;
00516 }
00517 
00518 void RGB_Matrix::SetOrientation(uint8_t orientation) {
00519     _orientation = orientation;
00520 }
00521 
00522 void RGB_Matrix::locate(uint8_t x, uint8_t y) {
00523     char_x = x * font[FONTHEIGHT];
00524     char_y = y * font[FONTHEIGHT];
00525 }
00526 
00527 void RGB_Matrix::locatePixelX(uint8_t x) {
00528     char_x = x;
00529 }
00530 
00531 void RGB_Matrix::locatePixelY(uint8_t y) {
00532     char_y = y;
00533 }
00534 
00535 int RGB_Matrix::columns() {
00536     return width() / font[FONTHEIGHT];
00537 }
00538 
00539 int RGB_Matrix::rows() {
00540     return height() / font[FONTHEIGHT];
00541 }
00542 
00543 void RGB_Matrix::setDisplayBuffer(uint8_t Buffer) {
00544     bufferDisplay = Buffer;
00545 }
00546 
00547 void RGB_Matrix::setWriteBuffer(uint8_t Buffer) {
00548     bufferWrite = Buffer;
00549 }
00550 
00551 void RGB_Matrix::updateDisplay2(void) {
00552     _Pin_OE  = 1;  // Disable LED output during row/plane switchover
00553     _Pin_LAT = 1; // Latch data loaded during *prior* interrupt
00554     _Pin_A   = (row & 0x01);
00555     _Pin_B   = (row & 0x02) >> 1;
00556     _Pin_C   = (row & 0x04) >> 2;
00557     _Pin_D   = (row & 0x08) >> 3;
00558     _Pin_OE  = 0;   // Re-enable output
00559     _Pin_LAT = 0;  // Latch down
00560 
00561     if(++plane >= PLANES) {      // Advance plane counter.  Maxed out?
00562         plane = 0;                // Yes, reset to plane 0, and
00563     }
00564     if(++row >= ROWS) {       // advance row counter.  Maxed out?
00565         row = 0;              // Yes, reset row counter, then...
00566     }
00567 
00568     buffptr = matrixbuff[bufferDisplay]; // Set first buffer
00569 
00570     for(int x = 0; x < WIDTH; x++) {
00571         int16_t BufferIndex1 = x + row * WIDTH;
00572         int16_t BufferIndex2 = BufferIndex1 + ROWS * WIDTH;
00573 
00574         uint8_t PixelValueR1 =  buffptr[BufferIndex1] & 0x03;
00575         uint8_t PixelValueG1 = (buffptr[BufferIndex1] >> 2) & 0x03;
00576         uint8_t PixelValueB1 = (buffptr[BufferIndex1] >> 4) & 0x03;
00577         uint8_t PixelValueR2 =  buffptr[BufferIndex2] & 0x03;
00578         uint8_t PixelValueG2 = (buffptr[BufferIndex2] >> 2) & 0x03;
00579         uint8_t PixelValueB2 = (buffptr[BufferIndex2] >> 4) & 0x03;
00580 
00581         if (PixelValueR1 >= plane+1) {
00582             _Pin_R1 = 1;
00583         } else {
00584             _Pin_R1 = 0;
00585         }
00586         if (PixelValueG1 >= plane+1) {
00587             _Pin_G1 = 1;
00588         } else {
00589             _Pin_G1 = 0;
00590         }
00591         if (PixelValueB1 >= plane+1) {
00592             _Pin_B1 = 1;
00593         } else {
00594             _Pin_B1 = 0;
00595         }
00596 
00597         if (PixelValueR2 >= plane+1) {
00598             _Pin_R2 = 1;
00599         } else {
00600             _Pin_R2 = 0;
00601         }
00602         if (PixelValueG2 >= plane+1) {
00603             _Pin_G2 = 1;
00604         } else {
00605             _Pin_G2 = 0;
00606         }
00607         if (PixelValueB2 >= plane+1) {
00608             _Pin_B2 = 1;
00609         } else {
00610             _Pin_B2 = 0;
00611         }
00612 
00613         _Pin_CLK = 0; // Clock low
00614         _Pin_CLK = 1; // Clock high
00615     }
00616 }
00617 
00618 void RGB_Matrix::updateDisplay(void) {
00619     _Pin_OE  = 1;  // Disable LED output during row/plane switchover
00620     _Pin_LAT = 1; // Latch data loaded during *prior* interrupt
00621     _Pin_A   =  row & 0x01;
00622     _Pin_B   = (row >> 1) & 0x01;
00623     _Pin_C   = (row >> 2) & 0x01;
00624     _Pin_D   = (row >> 3) & 0x01;
00625     _Pin_OE  = 0;   // Re-enable output
00626     _Pin_LAT = 0;  // Latch down
00627 
00628     if(++plane >= PLANES) {       // Advance plane counter.  Maxed out?
00629         plane = 0;                // Yes, reset to plane 0, and
00630         if(++row >= ROWS) {       // advance row counter.  Maxed out?
00631             row = 0;              // Yes, reset row counter, then...
00632         }
00633     }
00634 
00635     buffptr = matrixbuff[bufferDisplay]; // Set display buffer
00636     for(uint8_t x = 0; x < WIDTH; x++) {
00637         uint16_t BufferIndex = x + row * WIDTH + plane * PIXELS;
00638         _Pin_R1  =  buffptr[BufferIndex] & 0x01;
00639         _Pin_G1  = (buffptr[BufferIndex] >> 1) & 0x01;
00640         _Pin_B1  = (buffptr[BufferIndex] >> 2) & 0x01;
00641         _Pin_R2  = (buffptr[BufferIndex] >> 4) & 0x01;
00642         _Pin_G2  = (buffptr[BufferIndex] >> 5) & 0x01;
00643         _Pin_B2  = (buffptr[BufferIndex] >> 6) & 0x01;
00644         _Pin_CLK = 0; // Clock low
00645         _Pin_CLK = 1; // Clock high
00646     }
00647 }