Chris Taylor / Mbed 2 deprecated RETRO-CityRally

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LCD_ST7735.cpp Source File

LCD_ST7735.cpp

00001 #include "mbed.h"
00002 #include "LCD_ST7735.h"
00003 
00004 const uint16_t LCD_ST7735::DefaultPalette[] = {
00005     0x0000, // 0  - Black
00006     0x0019, // 1  - Blue
00007     0xc800, // 2  - Red
00008     0xc819, // 3  - Magenta
00009     0x0660, // 4  - Green
00010     0x0679, // 5  - Cyan
00011     0xce60, // 6  - Yellow
00012     0xce79, // 7  - White        
00013     0x001f, // 8  - Bright Blue
00014     0xf800, // 9  - Bright Red
00015     0xf81f, // 10 - Bright Magenta
00016     0x07e0, // 11 - Bright Green
00017     0x07ff, // 12 - Bright Cyan
00018     0xffe0, // 13 - Bright Yellow
00019     0xffff, // 14 - Bright White
00020 };
00021 
00022 LCD_ST7735::LCD_ST7735(
00023     PinName backlightPin,
00024     PinName resetPin,
00025     PinName dsPin,
00026     PinName mosiPin,
00027     PinName misoPin,
00028     PinName clkPin,
00029     PinName csPin,
00030     PanelColorFilter colorFilter
00031     ) :
00032         _colorFilter(colorFilter),
00033         _backlight(backlightPin, 0),
00034         _reset(resetPin, 1),
00035         _ds(dsPin, 0),
00036         _cs(csPin, 1),
00037         _spi(mosiPin, misoPin, clkPin)        
00038 {        
00039     _spi.format(8, 3);
00040     _spi.frequency(18000000);
00041     
00042     initDisplay();
00043     clearScreen();
00044     setForegroundColor(0xffff);
00045     setBackgroundColor(0x0000);    
00046     
00047     _palette = (uint16_t*)DefaultPalette;    
00048 }
00049 
00050 void LCD_ST7735::setOrientation(Orientation orientation, bool flip)
00051 {
00052     const static uint8_t my = 0x80; 
00053     const static uint8_t mx = 0x40;
00054     const static uint8_t mv = 0x20;
00055     
00056     uint8_t madctlData = _colorFilter;
00057     switch(orientation)
00058     {
00059         case Rotate0:
00060             _width = 128;
00061             _height = 160;
00062             madctlData |= flip ? mx : 0;
00063             break;
00064             
00065         case Rotate90:
00066             _width = 160;
00067             _height = 128;
00068             madctlData |= flip ? my | mv | mx : mv | mx;
00069             break;
00070             
00071         case Rotate180:
00072             _width = 128;
00073             _height = 160;
00074             madctlData |= flip ? my : mx | my;
00075             break;
00076             
00077         case Rotate270:
00078             _width = 160;
00079             _height = 128;
00080             madctlData |= flip ? mv : mv | my;
00081             break;
00082     }
00083     write(CMD_MADCTL, (uint8_t[]){madctlData}, 1);
00084 }
00085 
00086 int LCD_ST7735::getWidth()
00087 {
00088     return _width;
00089 }
00090         
00091 int LCD_ST7735::getHeight()
00092 {
00093     return _height;
00094 }
00095 
00096 void LCD_ST7735::setBacklight(bool state)
00097 {
00098     _backlight = state ? 1 : 0;
00099 }
00100 
00101 void LCD_ST7735::setPalette(uint16_t *palette)
00102 {
00103     _palette = palette;
00104 }
00105 
00106 void LCD_ST7735::clearScreen(uint16_t color)
00107 {
00108     clipRect(0, 0, _width - 1, _height - 1);
00109     beginBatchCommand(CMD_RAMWR);
00110     uint8_t colorHigh = color >> 8;
00111     uint8_t colorLow = color;
00112     for(int i = 0; i < 128 * 160 * 2; ++i)
00113     {
00114         writeBatchData(colorHigh, colorLow);
00115     }
00116     endBatchCommand();
00117 }
00118 
00119 void LCD_ST7735::setPixel(int x, int y, uint16_t color)
00120 {
00121     write(CMD_CASET, (uint8_t[]){0, x, 0, x}, 4);    
00122     write(CMD_RASET, (uint8_t[]){0, y, 0, y}, 4);    
00123     write(CMD_RAMWR, color);
00124 }
00125 
00126 void LCD_ST7735::drawLine(int x1, int y1, int x2, int y2, uint16_t color)
00127 {
00128     int dx = abs(x2 - x1);
00129     int dy = abs(y2 - y1);
00130     
00131     if (dx == 0) 
00132     {
00133         if (y1 > y2) swap(y1, y2);
00134         drawVertLine(x1, y1, y2, color);
00135         return;
00136     }
00137     else if(dy == 0)
00138     {
00139         if (x1 > x2) swap(x1, x2);
00140         drawHorizLine(x1, y1, x2, color);
00141         return;
00142     }
00143    
00144     int sx = (x1 < x2) ? 1 : -1;
00145     int sy = (y1 < y2) ? 1 : -1;
00146     int err = dx - dy;
00147     while(x1 != x2 || y1 != y2)
00148     {
00149         setPixel(x1, y1, color);
00150         int e2 = err << 1;
00151         if (e2 > -dy)
00152         {
00153             err -= dy;
00154             x1 += sx;            
00155         }
00156         if (e2 < dx)
00157         {
00158             err += dx;
00159             y1 += sy;
00160         }
00161     }
00162     setPixel(x2, y2, color);
00163 }
00164 
00165 void LCD_ST7735::swap(int &a, int &b)
00166 {
00167     int t = a;
00168     a = b;
00169     b = t;
00170 }
00171 
00172 void LCD_ST7735::drawRect(int x1, int y1, int x2, int y2, uint16_t color)
00173 {
00174     if (x1 > x2) swap(x1, x2);
00175     if (y1 > y2) swap(y1, y2);
00176     
00177     drawHorizLine(x1, y1, x2, color);
00178     drawHorizLine(x1, y2, x2, color);
00179     drawVertLine(x1, y1, y2, color);
00180     drawVertLine(x2, y1, y2, color);
00181 }
00182 
00183 void LCD_ST7735::drawCircle(int x, int y, int r, uint16_t color)
00184 {
00185     int ix = r;
00186     int iy = 0;
00187     int err = 1 - r;
00188     
00189     while(ix >= iy)
00190     {
00191         setPixel(x + ix, y + iy, color);
00192         setPixel(x + iy, y + ix, color);
00193         setPixel(x - ix, y + iy, color);
00194         setPixel(x - iy, y + ix, color);
00195         setPixel(x - ix, y - iy, color);
00196         setPixel(x - iy, y - ix, color);
00197         setPixel(x + ix, y - iy, color);
00198         setPixel(x + iy, y - ix, color);
00199         iy++;
00200         if (err < 0)
00201         {
00202             err += 2 * iy + 1;
00203         }
00204         else
00205         {
00206             ix--;
00207             err += 2 * (iy - ix + 1);
00208         }
00209     }
00210 }
00211 
00212 void LCD_ST7735::drawEllipse(int x, int y, int rx, int ry, uint16_t color)
00213 {
00214     int a2 = rx * rx;
00215     int b2 = ry * ry;
00216     int fa2 = 4 * a2;
00217     int fb2 = 4 * b2;
00218     
00219     int ix, iy, sigma;    
00220     for (ix = 0, iy = ry, sigma = 2 * b2 + a2 * (1 - 2 * ry); b2 * ix <= a2 * iy; ix++)
00221     {
00222         setPixel(x + ix, y + iy, color);
00223         setPixel(x - ix, y + iy, color);
00224         setPixel(x + ix, y - iy, color);
00225         setPixel(x - ix, y - iy, color);
00226         if (sigma >= 0)
00227         {
00228             sigma+= fa2 * (1 - iy);
00229             iy--;
00230         }
00231         sigma += b2 * ((4 * ix) + 6);
00232     }
00233     
00234     for (ix = rx, iy = 0, sigma = 2 * a2 + b2 * (1 - 2 * rx); a2 * iy <= b2 * ix; iy++)
00235     {
00236         setPixel(x + ix, y + iy, color);
00237         setPixel(x - ix, y + iy, color);
00238         setPixel(x + ix, y - iy, color);
00239         setPixel(x - ix, y - iy, color);
00240         if (sigma >= 0)
00241         {
00242             sigma+= fb2 * (1 - ix);
00243             ix--;
00244         }
00245         sigma += a2 * ((4 * iy) + 6);
00246     }
00247 }
00248 void LCD_ST7735::fillRect(int x1, int y1, int x2, int y2, uint16_t fillColor)
00249 {
00250     clipRect(x1, y1, x2, y2);
00251     int c = ((x2-x1) * (y2-y1)) << 1;
00252     uint8_t colorHigh = fillColor >> 8;
00253     uint8_t colorLow = fillColor;
00254     beginBatchCommand(CMD_RAMWR);
00255     while(c--)
00256     {
00257         writeBatchData(colorHigh, colorLow);
00258     }
00259     endBatchCommand();
00260 }
00261 
00262 void LCD_ST7735::fillRect(int x1, int y1, int x2, int y2, uint16_t borderColor, uint16_t fillColor)
00263 {
00264     if (x1 > x2) swap(x1, x2);
00265     if (y1 > y2) swap(y1, y2);
00266     
00267     drawRect(x1, y1, x2, y2, borderColor);
00268     ++x1; ++y1; --x2; --y2;
00269     if (x2 >= x1 && y2 >= y1)
00270     {
00271         clipRect(x1, y1, x2, y2);
00272         int c = ((x2-x1-2) * (y2-y1-2)) << 1;
00273         uint8_t colorHigh = fillColor >> 8;
00274         uint8_t colorLow = fillColor;
00275         beginBatchCommand(CMD_RAMWR);
00276         while(c--)
00277         {
00278             writeBatchData(colorHigh, colorLow);
00279         }
00280         endBatchCommand();
00281     }
00282 }
00283 
00284 void LCD_ST7735::fillCircle(int x, int y, int r, uint16_t borderColor, uint16_t fillColor)
00285 {
00286     int ix = r;
00287     int iy = 0;
00288     int err = 1 - r;
00289     
00290     while(ix >= iy)
00291     {
00292         setPixel(x - ix, y + iy, borderColor);
00293         setPixel(x + ix, y + iy, borderColor);        
00294         drawHorizLine(x - ix + 1, y + iy, x + ix - 1, fillColor);
00295         
00296         setPixel(x - iy, y + ix, borderColor);
00297         setPixel(x + iy, y + ix, borderColor);                
00298         drawHorizLine(x - iy + 1, y + ix, x + iy - 1, fillColor);
00299                 
00300         setPixel(x - ix, y - iy, borderColor);
00301         setPixel(x + ix, y - iy, borderColor);
00302         drawHorizLine(x - ix + 1, y - iy, x + ix - 1, fillColor);
00303         
00304         setPixel(x - iy, y - ix, borderColor);        
00305         setPixel(x + iy, y - ix, borderColor);
00306         drawHorizLine(x - iy + 1, y - ix, x + iy - 1, fillColor);
00307         iy++;
00308         if (err < 0)
00309         {
00310             err += 2 * iy + 1;
00311         }
00312         else
00313         {
00314             ix--;
00315             err += 2 * (iy - ix + 1);
00316         }
00317     }
00318 }
00319 
00320 void LCD_ST7735::fillEllipse(int x, int y, int rx, int ry, uint16_t borderColor, uint16_t fillColor)
00321 {
00322     int a2 = rx * rx;
00323     int b2 = ry * ry;
00324     int fa2 = 4 * a2;
00325     int fb2 = 4 * b2;
00326     
00327     int ix, iy, sigma;    
00328     for (ix = 0, iy = ry, sigma = 2 * b2 + a2 * (1 - 2 * ry); b2 * ix <= a2 * iy; ix++)
00329     {
00330         setPixel(x + ix, y + iy, borderColor);
00331         setPixel(x - ix, y + iy, borderColor);
00332         drawHorizLine(x - ix + 1, y + iy, x + ix - 1, fillColor);
00333         
00334         setPixel(x + ix, y - iy, borderColor);
00335         setPixel(x - ix, y - iy, borderColor);
00336         drawHorizLine(x - ix + 1, y - iy, x + ix - 1, fillColor);
00337         
00338         if (sigma >= 0)
00339         {
00340             sigma+= fa2 * (1 - iy);
00341             iy--;
00342         }
00343         sigma += b2 * ((4 * ix) + 6);
00344     }
00345     
00346     for (ix = rx, iy = 0, sigma = 2 * a2 + b2 * (1 - 2 * rx); a2 * iy <= b2 * ix; iy++)
00347     {
00348         setPixel(x + ix, y + iy, borderColor);
00349         setPixel(x - ix, y + iy, borderColor);
00350         drawHorizLine(x - ix + 1, y + iy, x + ix - 1, fillColor);
00351         
00352         setPixel(x + ix, y - iy, borderColor);
00353         setPixel(x - ix, y - iy, borderColor);
00354         drawHorizLine(x - ix + 1, y - iy, x + ix - 1, fillColor);
00355         if (sigma >= 0)
00356         {
00357             sigma+= fb2 * (1 - ix);
00358             ix--;
00359         }
00360         sigma += a2 * ((4 * iy) + 6);
00361     }
00362 }
00363 
00364 void LCD_ST7735::drawBitmap(int x, int y, const uint16_t *pbmp)
00365 {
00366     int w = *pbmp++;
00367     int h = *pbmp++;
00368     
00369     drawBitmap(x, y, pbmp, 0, 0, w, h);
00370 }
00371 
00372 void LCD_ST7735::drawBitmap(int x, int y, const uint16_t *pbmp, int srcX, int srcY, int srcWidth, int srcHeight)
00373 {
00374     // Clip if out of screen    
00375     if ((x >= _width) || (x + srcWidth < 0) || 
00376         (y >= _height) || (y + srcHeight < 0))
00377     {
00378         return;
00379     }
00380     
00381     // Clip X
00382     if (x < 0) { srcX += -x; srcWidth += x; x = 0; }
00383     if (x + srcWidth >= _width) { srcWidth += _width - (x + srcWidth); }
00384     
00385     // Clip Y
00386     if (y  < 0) {srcY += -y; srcHeight += y; y = 0; }  
00387     if (y + srcHeight >= _height) { srcHeight += _height - (y + srcHeight); }
00388     
00389     int w = *pbmp++;
00390     int h = *pbmp++;
00391     
00392     clip(x, y, srcWidth, srcHeight);
00393     beginBatchCommand(CMD_RAMWR);    
00394     const uint16_t *p = pbmp + srcX + (srcY * w);
00395     for(int iy = 0; iy < srcHeight; ++iy)
00396     {
00397         for(int ix = 0; ix < srcWidth; ++ix)
00398         {
00399             writeBatchData(*(p + ix));
00400         }
00401         p += w;
00402     } 
00403     endBatchCommand();
00404 }
00405 
00406 void LCD_ST7735::drawBitmap(int x, int y, Bitmap2bpp &bmp, int srcX, int srcY, int srcWidth, int srcHeight)
00407 {
00408     // Clip if out of screen    
00409     if ((x >= _width) || (x + srcWidth < 0) || 
00410         (y >= _height) || (y + srcHeight < 0))
00411     {
00412         return;
00413     }
00414     
00415     // Clip X
00416     if (x < 0) { srcX += -x; srcWidth += x; x = 0; }
00417     if (x + srcWidth >= _width) { srcWidth += _width - (x + srcWidth); }
00418     
00419     // Clip Y
00420     if (y  < 0) {srcY += -y; srcHeight += y; y = 0; }  
00421     if (y + srcHeight >= _height) { srcHeight += _height - (y + srcHeight); }
00422     
00423     int offset = (bmp.getStride() * srcY) + (srcX / 4);
00424     int startbits = 6 - ((srcX % 4) << 1);
00425     
00426     clip(x, y, srcWidth, srcHeight);
00427     beginBatchCommand(CMD_RAMWR);
00428     for(int r = 0; r < srcHeight; ++r)
00429     {
00430         const uint8_t *p = bmp.getBitmapData() + offset;
00431         
00432         uint8_t b = *p;
00433         for (int c = 0, shift = startbits; c < srcWidth; ++c, shift -= 2)
00434         {
00435             if (shift < 0) 
00436             {
00437                 shift = 6;
00438                 b = *++p;
00439             }
00440             
00441             uint8_t colorIndex = (b >> shift) & 0x03;
00442             writeBatchData(_palette[colorIndex]);            
00443         }   
00444         offset += bmp.getStride();             
00445     }
00446     endBatchCommand();
00447 }
00448 
00449 
00450 void LCD_ST7735::drawBitmap(int x, int y, Bitmap4bpp &bmp, int srcX, int srcY, int srcWidth, int srcHeight)
00451 {
00452     // Clip if out of screen    
00453     if ((x >= _width) || (x + srcWidth < 0) || 
00454         (y >= _height) || (y + srcHeight < 0))
00455     {
00456         return;
00457     }
00458     
00459     // Clip X
00460     if (x < 0) { srcX += -x; srcWidth += x; x = 0; }
00461     if (x + srcWidth >= _width) { srcWidth += _width - (x + srcWidth); }
00462     
00463     // Clip Y
00464     if (y  < 0) {srcY += -y; srcHeight += y; y = 0; }  
00465     if (y + srcHeight >= _height) { srcHeight += _height - (y + srcHeight); }
00466     
00467     int stride = bmp.getStride();
00468     
00469     bool oddStart = srcX & 0x01;
00470     bool oddWidth = srcWidth & 0x01;    
00471     bool oddEnd = oddStart ^ oddWidth;
00472     
00473     int startX = oddStart ? 1 : 0;
00474     int endX = (oddEnd ? srcWidth : srcWidth + 1) >> 1;    
00475     
00476     const uint8_t *p = bmp.getBitmapData() + (srcX >> 1) + (srcY * stride);    
00477 
00478     clip(x, y, srcWidth, srcHeight);
00479     beginBatchCommand(CMD_RAMWR);        
00480     for(int iy = 0; iy < srcHeight; ++iy, p += stride)
00481     {
00482         if (oddStart) writeBatchData(_palette[*p & 0x0f]);
00483         for(int ix = startX; ix < endX; ++ix)
00484         {
00485             uint8_t c = *(p + ix);
00486             writeBatchData(_palette[(c >> 4) & 0x0f]);
00487             writeBatchData(_palette[c & 0x0f]);
00488         }        
00489         if (oddEnd) writeBatchData(_palette[(*(p + endX) >> 4) & 0x0f]);
00490     } 
00491     endBatchCommand();
00492 }
00493 
00494 void LCD_ST7735::drawBitmap(int x, int y, Bitmap1bpp &bmp, int srcX, int srcY, int srcWidth, int srcHeight, uint16_t foregroundColor, uint16_t backgroundColor)
00495 {
00496     // Clip if out of screen    
00497     if ((x >= _width) || (x + srcWidth < 0) || 
00498         (y >= _height) || (y + srcHeight < 0))
00499     {
00500         return;
00501     }
00502     
00503     // Clip X
00504     if (x < 0) { srcX += -x; srcWidth += x; x = 0; }
00505     if (x + srcWidth >= _width) { srcWidth += _width - (x + srcWidth); }
00506     
00507     // Clip Y
00508     if (y  < 0) {srcY += -y; srcHeight += y; y = 0; }  
00509     if (y + srcHeight >= _height) { srcHeight += _height - (y + srcHeight); }
00510     
00511     uint8_t fch = foregroundColor >> 8;
00512     uint8_t fcl = foregroundColor;
00513     uint8_t bch = backgroundColor >> 8;
00514     uint8_t bcl = backgroundColor;
00515     
00516     clip(x, y, srcWidth, srcHeight);
00517     
00518     int offset = (bmp.getStride() * srcY) + (srcX / 8);
00519     int startbits = srcX % 8;
00520     
00521     beginBatchCommand(CMD_RAMWR);
00522     for(int r = 0; r < srcHeight; ++r)
00523     {
00524         const uint8_t *p = bmp.getBitmapData() + offset;
00525         
00526         uint8_t b = *p;
00527         for (int c = 0, shift = startbits; c < srcWidth; ++c, ++shift)
00528         {
00529             if (shift == 8) 
00530             {
00531                 shift = 0;
00532                 b = *++p;
00533             }
00534             
00535             if ((b << shift) & 0x80)                            
00536             {
00537                 writeBatchData(fch, fcl);                
00538             }
00539             else
00540             {
00541                 writeBatchData(bch, bcl);                
00542             }
00543         }   
00544         offset += bmp.getStride();             
00545     }
00546     endBatchCommand();
00547 }
00548 
00549 void LCD_ST7735::drawBitmap(int x, int y, const uint8_t *pbmp, int srcX, int srcY, int srcWidth, int srcHeight, uint16_t foregroundColor, uint16_t backgroundColor)
00550 {
00551     // Clip if out of screen    
00552     if ((x >= _width) || (x + srcWidth < 0) || 
00553         (y >= _height) || (y + srcHeight < 0))
00554     {
00555         return;
00556     }
00557     
00558     // Clip X
00559     if (x < 0) { srcX += -x; srcWidth += x; x = 0; }
00560     if (x + srcWidth >= _width) { srcWidth += _width - (x + srcWidth); }
00561     
00562     // Clip Y
00563     if (y  < 0) {srcY += -y; srcHeight += y; y = 0; }  
00564     if (y + srcHeight >= _height) { srcHeight += _height - (y + srcHeight); }
00565     
00566     uint8_t fch = foregroundColor >> 8;
00567     uint8_t fcl = foregroundColor;
00568     uint8_t bch = backgroundColor >> 8;
00569     uint8_t bcl = backgroundColor;
00570     
00571     uint16_t w = (*(pbmp + 1) << 8) | (*(pbmp + 0));    
00572     pbmp += 4;
00573     
00574     int stride = w / 8;
00575     clip(x, y, srcWidth, srcHeight);
00576     
00577     int offset = (stride * srcY) + (srcX / 8);
00578     int startbits = srcX % 8;
00579     
00580     beginBatchCommand(CMD_RAMWR);
00581     for(int r = 0; r < srcHeight; ++r)
00582     {
00583         const uint8_t *p = pbmp + offset;
00584         
00585         uint8_t b = *p;
00586         for (int c = 0, shift = startbits; c < srcWidth; ++c, ++shift)
00587         {
00588             if (shift == 8) 
00589             {
00590                 shift = 0;
00591                 b = *++p;
00592             }
00593             
00594             if ((b << shift) & 0x80)                            
00595             {
00596                 writeBatchData(fch, fcl);                
00597             }
00598             else
00599             {
00600                 writeBatchData(bch, bcl);                
00601             }
00602         }   
00603         offset += stride;             
00604     }
00605     endBatchCommand();
00606 }
00607 
00608 void LCD_ST7735::setForegroundColor(uint16_t color)
00609 {
00610     _foregroundColorHigh = color >> 8;
00611     _foregroundColorLow = color;
00612 }
00613 
00614 void LCD_ST7735::setBackgroundColor(uint16_t color)
00615 {
00616     _backgroundColorHigh = color >> 8;
00617     _backgroundColorLow = color;
00618 }
00619         
00620 void LCD_ST7735::drawString(const uint8_t *pFont, int x, int y, const char *pString)
00621 {
00622     char *p = (char*)pString;
00623     while(*p != 0)
00624     {
00625         drawChar(pFont, x, y, *p++);
00626         x += 8;
00627     }
00628 }
00629 
00630 void LCD_ST7735::selectDevice()
00631 {
00632     _spi.prepareFastSPI();
00633 }
00634 
00635 void LCD_ST7735::drawVertLine(int x1, int y1, int y2, uint16_t color)
00636 {
00637     clipRect(x1, y1, x1, y2);
00638     beginBatchCommand(CMD_RAMWR);
00639     int c = (y2 - y1) << 1;
00640     uint8_t colorHigh = color >> 8;
00641     uint8_t colorLow = color;
00642     for (int i = 0; i < c; ++i)
00643     {
00644         writeBatchData(colorHigh, colorLow);        
00645     }
00646     endBatchCommand();
00647 }
00648 
00649 void LCD_ST7735::drawHorizLine(int x1, int y1, int x2, uint16_t color)
00650 {    
00651     clipRect(x1, y1, x2, y1);
00652     beginBatchCommand(CMD_RAMWR);
00653     int c = (x2 - x1) << 1;
00654     uint8_t colorHigh = color >> 8;
00655     uint8_t colorLow = color;
00656     for (int i = 0; i < c; ++i)
00657     {
00658         writeBatchData(colorHigh, colorLow);
00659     }
00660     endBatchCommand();
00661 }
00662 
00663 void LCD_ST7735::drawChar(const uint8_t *pFont, int x, int y, char c)
00664 {
00665     const uint8_t *pChar = pFont + (c * 8);
00666     
00667     clip(x, y, 8, 8);
00668     beginBatchCommand(CMD_RAMWR);
00669     for(int r = 0; r < 8; ++r)
00670     {
00671         uint8_t b = pChar[r];
00672         for(int c = 0; c < 8; ++c)
00673         {
00674             if (b & 0x80)
00675             {
00676                 writeBatchData(_foregroundColorHigh);
00677                 writeBatchData(_foregroundColorLow);
00678             }
00679             else
00680             {
00681                 writeBatchData(_backgroundColorHigh);
00682                 writeBatchData(_backgroundColorLow);
00683             }
00684                 
00685             b <<= 1;
00686         }
00687     }
00688     endBatchCommand();
00689 }
00690 
00691 void LCD_ST7735::initDisplay()
00692 {
00693     selectDevice();
00694     reset();
00695     
00696     writeCommand(CMD_SLPOUT);
00697     
00698     write(CMD_FRMCTR1, (uint8_t[]){0x01, 0x2c, 0x2d}, 3);
00699     write(CMD_FRMCTR2, (uint8_t[]){0x01, 0x2c, 0x2d}, 3);
00700     write(CMD_FRMCTR3, (uint8_t[]){0x01, 0x2c, 0x2d, 0x01, 0x2c, 0x2d}, 6);
00701     
00702     write(CMD_INVCTR, (uint8_t[]){0x07}, 1);
00703     
00704     write(CMD_PWCTR1, (uint8_t[]){0xa2, 0x02, 0x84}, 3);
00705     write(CMD_PWCTR2, (uint8_t[]){0xc5}, 1);
00706     write(CMD_PWCTR3, (uint8_t[]){0x0a, 0x00}, 2);
00707     write(CMD_PWCTR4, (uint8_t[]){0x8a, 0x2a}, 2);
00708     write(CMD_PWCTR5, (uint8_t[]){0x8a, 0xee}, 2);
00709     
00710     write(CMD_VMCTR1, (uint8_t[]){0x0e}, 1);
00711     
00712     write(CMD_MADCTL, (uint8_t[]){0xc0 | _colorFilter}, 1);
00713     
00714     // Gama sequence
00715     write(CMD_GAMCTRP1, (uint8_t[])
00716         {
00717             0x0f, 0x1a,
00718             0x0f, 0x18,
00719             0x2f, 0x28,
00720             0x20, 0x22,
00721             0x1f, 0x1b,
00722             0x23, 0x37,
00723             0x00, 0x07,
00724             0x02, 0x10
00725         }, 16);
00726         
00727     write(CMD_GAMCTRN1, (uint8_t[])
00728         {
00729             0x0f, 0x1b,
00730             0x0f, 0x17,
00731             0x33, 0x2c,
00732             0x29, 0x2e,
00733             0x30, 0x30,
00734             0x39, 0x3f,
00735             0x00, 0x07,
00736             0x03, 0x10
00737         }, 16);
00738         
00739     write(CMD_CASET, (uint8_t[]){0x00, 0x00, 0x00, 0x7f}, 4);
00740     write(CMD_RASET, (uint8_t[]){0x00, 0x00, 0x00, 0x9f}, 4);
00741     
00742     write(CMD_EXTCTRL, (uint8_t[]){0x01}, 1);            
00743     
00744     // Disable RAM power save
00745     write(0xf6, (uint8_t[]){0x00}, 1);                    
00746     
00747     // 65k color mode
00748     write(CMD_COLMOD, (uint8_t[]){0x05}, 1);            
00749     
00750     // Enable display
00751     writeCommand(CMD_DISPON);            
00752     
00753     setBacklight(true);
00754 }
00755 
00756 void LCD_ST7735::reset()
00757 {
00758     _reset = 0;
00759     wait_us(100);
00760     _reset = 1;
00761     wait_us(100);
00762 }
00763 
00764 void LCD_ST7735::clip(int x, int y, int w, int h)
00765 {
00766     clipRect(x, y, (x + w) - 1, (y + h) - 1);
00767 }
00768 
00769 void LCD_ST7735::clipRect(int x1, int y1, int x2, int y2)
00770 {
00771     uint8_t x1l = (uint8_t)x1;
00772     //uint8_t x1h = (uint8_t)(x1 >> 8);
00773     uint8_t x2l = (uint8_t)x2;
00774     //uint8_t x2h = (uint8_t)(x2 >> 8);
00775     write(CMD_CASET, (uint8_t[]){0, x1l, 0, x2l}, 4);    
00776     
00777     uint8_t y1l = (uint8_t)y1;
00778     //uint8_t y1h = (uint8_t)(y1 >> 8);
00779     uint8_t y2l = (uint8_t)y2;
00780     //uint8_t y2h = (uint8_t)(y2 >> 8);
00781     write(CMD_RASET, (uint8_t[]){0, y1l, 0, y2l}, 4);    
00782 }
00783         
00784 void LCD_ST7735::writeCommand(uint8_t cmd)
00785 {
00786     _cs = 0;
00787     _ds = 0;    
00788     _spi.fastWrite(cmd);
00789     _spi.waitWhileBusy();
00790     _spi.clearRx();
00791     _cs = 1;
00792 }
00793 
00794 void LCD_ST7735::write(uint8_t cmd, uint8_t data[], int dataLen)
00795 {
00796     _cs = 0;
00797     _ds = 0;    
00798     _spi.fastWrite(cmd);
00799     _spi.waitWhileBusy();
00800     if (data != NULL & dataLen > 0)
00801     {
00802         _ds = 1;        
00803         for(int i = 0; i < dataLen; ++i)
00804         {            
00805             _spi.fastWrite(data[i]); 
00806         }        
00807         _spi.waitWhileBusy();
00808         _ds = 0; 
00809     }    
00810     _spi.clearRx();
00811     _cs = 1;
00812 }
00813 
00814 void LCD_ST7735::write(uint8_t cmd, uint16_t data)
00815 {
00816     _cs = 0; 
00817     _ds = 0;    
00818     _spi.fastWrite(cmd);       
00819     _spi.waitWhileBusy();
00820     _ds = 1;            
00821     _spi.fastWrite(data >> 8);
00822     _spi.fastWrite(data);
00823     _spi.waitWhileBusy();
00824     _spi.clearRx();
00825     _ds = 0;     
00826     _cs = 1;
00827 }
00828 
00829 void LCD_ST7735::beginBatchCommand(uint8_t cmd)
00830 {
00831     _cs = 0;
00832     _ds = 0;        
00833     _spi.fastWrite(cmd);   
00834     _spi.waitWhileBusy();
00835     _ds = 1;
00836 }
00837 
00838 void LCD_ST7735::writeBatchData(uint8_t data)
00839 {
00840     _spi.fastWrite(data);
00841 }
00842 
00843 void LCD_ST7735::writeBatchData(uint8_t dataHigh, uint8_t dataLow)
00844 {
00845     _spi.fastWrite(dataHigh);
00846     _spi.fastWrite(dataLow);
00847 }
00848 
00849 
00850 void LCD_ST7735::writeBatchData(uint16_t data)
00851 {
00852     _spi.fastWrite(data >> 8);
00853     _spi.fastWrite(data); 
00854 }
00855 
00856 void LCD_ST7735::endBatchCommand()
00857 {
00858     _spi.waitWhileBusy();
00859     _spi.clearRx();
00860     _ds = 0; 
00861     _cs = 1; 
00862 }
00863 
00864