Driver Library for our displays

Dependents:   dm_bubbles dm_calc dm_paint dm_sdcard_with_adapter ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DmTftBase.cpp Source File

DmTftBase.cpp

00001 /**********************************************************************************************
00002  Copyright (c) 2014 DisplayModule. All rights reserved.
00003 
00004  Redistribution and use of this source code, part of this source code or any compiled binary
00005  based on this source code is permitted as long as the above copyright notice and following
00006  disclaimer is retained.
00007 
00008  DISCLAIMER:
00009  THIS SOFTWARE IS SUPPLIED "AS IS" WITHOUT ANY WARRANTIES AND SUPPORT. DISPLAYMODULE ASSUMES
00010  NO RESPONSIBILITY OR LIABILITY FOR THE USE OF THE SOFTWARE.
00011  ********************************************************************************************/
00012 
00013 #include "DmTftBase.h"
00014 
00015 #define FONT_CHAR_WIDTH    8
00016 #define FONT_CHAR_HEIGHT  16
00017 extern uint8_t font[];
00018 
00019 /*
00020  * Macro to read the 8 bits representing one line of a character.
00021  * The macro is needed as the reading is handled differently on
00022  * Arduino and Mbed platforms.
00023  */
00024 #if defined (DM_TOOLCHAIN_ARDUINO)
00025   #define read_font_line(__char, __line) \
00026       pgm_read_byte(&font[((uint16_t)(__char))*FONT_CHAR_HEIGHT+(__line)])
00027 #elif defined (DM_TOOLCHAIN_MBED)
00028   #define read_font_line(__char, __line) \
00029       font[((uint16_t)(__char))*FONT_CHAR_HEIGHT+(__line)]
00030 #endif
00031 
00032 
00033 void DmTftBase::setPixel(uint16_t x, uint16_t y, uint16_t color) {
00034   cbi(_pinCS, _bitmaskCS);
00035 
00036   if ((x >= _width) || (y >= _height)) {
00037     return;
00038   }
00039 
00040   setAddress(x, y, x, y);
00041 
00042   sendData(color);
00043   sbi(_pinCS, _bitmaskCS);
00044 }
00045 
00046 void DmTftBase::clearScreen(uint16_t color) {
00047   cbi(_pinCS, _bitmaskCS);
00048 
00049   setAddress(0,0,_width-1, _height-1);
00050 
00051   for(uint16_t i=0; i<_height; i++) {
00052     for(uint16_t j=0; j<_width; j++) {
00053         sendData(color);
00054     }
00055   }
00056 
00057   sbi(_pinCS, _bitmaskCS);
00058 }
00059 
00060 void  DmTftBase::drawHorizontalLine(uint16_t x, uint16_t y, uint16_t length, uint16_t color) {
00061   cbi(_pinCS, _bitmaskCS);
00062 
00063   setAddress(x, y, x + length, y);
00064 
00065   for (int i = 0; i <= length; i++) {
00066     sendData(color);
00067   }
00068 
00069   sbi(_pinCS, _bitmaskCS);
00070 }
00071 
00072 void DmTftBase::drawVerticalLine(uint16_t x, uint16_t y, uint16_t length, uint16_t color) {
00073   cbi(_pinCS, _bitmaskCS);
00074 
00075   setAddress(x, y, x, y + length);
00076 
00077   for (int i = 0; i <= length; i++) {
00078     sendData(color);
00079   }
00080 
00081   sbi(_pinCS, _bitmaskCS);
00082 }
00083 
00084 void DmTftBase::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) {
00085   int x = x1-x0;
00086   int y = y1-y0;
00087   int dx = abs(x), sx = x0<x1 ? 1 : -1;
00088   int dy = -abs(y), sy = y0<y1 ? 1 : -1;
00089   int err = dx+dy, e2;  /* error value e_xy             */
00090   for (;;) {
00091     setPixel(x0,y0,color);
00092     e2 = 2*err;
00093     if (e2 >= dy) {      /* e_xy+e_x > 0                 */
00094       if (x0 == x1) {
00095         break;
00096       }
00097       err += dy; x0 += sx;
00098     }
00099     if (e2 <= dx) { /* e_xy+e_y < 0   */
00100       if (y0 == y1) {
00101         break;
00102       }
00103       err += dx; y0 += sy;
00104     }
00105   }
00106 }
00107 
00108 void DmTftBase::drawRectangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) {
00109   // Make sure x0,y0 are in the top left corner
00110   if(x0 > x1) {
00111     x0 = x0^x1;
00112     x1 = x0^x1;
00113     x0 = x0^x1;
00114   }
00115   if(y0 > y1) {
00116     y0 = y0^y1;
00117     y1 = y0^y1;
00118     y0 = y0^y1;
00119   }
00120 
00121   drawHorizontalLine(x0, y0, x1-x0, color);
00122   drawHorizontalLine(x0, y1, x1-x0, color);
00123   drawVerticalLine(x0, y0, y1-y0, color);
00124   drawVerticalLine(x1, y0, y1-y0, color);
00125 }
00126 
00127 void DmTftBase::fillRectangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) {
00128   unsigned long numPixels=0;
00129   unsigned long i=0;
00130 
00131   // Make sure x0,y0 are in the top left corner
00132   if(x0 > x1) {
00133     x0 = x0^x1;
00134     x1 = x0^x1;
00135     x0 = x0^x1;
00136   }
00137   if(y0 > y1) {
00138     y0 = y0^y1;
00139     y1 = y0^y1;
00140     y0 = y0^y1;
00141   }
00142 
00143   x0 = constrain(x0, 0, _width-1);
00144   x1 = constrain(x1, 0, _width-1);
00145   y0 = constrain(y0, 0, _height-1);
00146   y1 = constrain(y1, 0, _height-1);
00147 
00148   numPixels = (x1-x0+1);
00149   numPixels = numPixels*(y1-y0+1);
00150 
00151   cbi(_pinCS, _bitmaskCS);
00152   setAddress(x0,y0,x1,y1);/* start to write to display ra */
00153 
00154   for(i=0; i < numPixels; i++) {
00155     sendData(color);
00156   }
00157 
00158   sbi(_pinCS, _bitmaskCS);
00159 }
00160 
00161 void DmTftBase::drawCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color) {
00162   int x = -r, y = 0, err = 2-2*r, e2;
00163   do {
00164     setPixel(x0-x, y0+y, color);
00165     setPixel(x0+x, y0+y, color);
00166     setPixel(x0+x, y0-y, color);
00167     setPixel(x0-x, y0-y, color);
00168     e2 = err;
00169     if (e2 <= y) {
00170       err += ++y*2+1;
00171       if (-x == y && e2 <= x) {
00172         e2 = 0;
00173       }
00174     }
00175     if (e2 > x) {
00176       err += ++x * 2 + 1;
00177     }
00178   } while (x <= 0);
00179 }
00180 
00181 void DmTftBase::fillCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color) {
00182   int x = -r, y = 0, err = 2-2*r, e2;
00183   do {
00184     drawVerticalLine(x0-x, y0-y, 2*y, color);
00185     drawVerticalLine(x0+x, y0-y, 2*y, color);
00186 
00187     e2 = err;
00188     if (e2 <= y) {
00189       err += ++y * 2 + 1;
00190       if (-x == y && e2 <= x) {
00191         e2 = 0;
00192       }
00193     }
00194     if (e2 > x) {
00195       err += ++x*2+1;
00196     }
00197   } while (x <= 0);
00198 }
00199 
00200 void DmTftBase::drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
00201   drawLine(x0, y0, x1, y1, color);
00202   drawLine(x0, y0, x2, y2, color);
00203   drawLine(x1, y1, x2, y2, color);
00204 }
00205 
00206 void DmTftBase::drawPoint(uint16_t x, uint16_t y, uint16_t radius) {
00207   if (radius == 0) {
00208     cbi(_pinCS, _bitmaskCS);
00209 
00210     setAddress(x,y,x,y);
00211     sendData(_fgColor);
00212 
00213     sbi(_pinCS, _bitmaskCS);
00214   } else {
00215     fillRectangle(x-radius,y-radius,x+radius,y+radius, _fgColor);
00216   }
00217 }
00218 
00219 void DmTftBase::drawChar(uint16_t x, uint16_t y, char ch, bool transparent) {
00220   cbi(_pinCS, _bitmaskCS);
00221 
00222   uint8_t temp;
00223   uint8_t pos,t;
00224 
00225   if ((x > (_width - FONT_CHAR_WIDTH)) || (y > (_height - FONT_CHAR_HEIGHT))) {
00226     return;
00227   }
00228 
00229   ch=ch-' ';
00230   if (!transparent) { // Clear background
00231     setAddress(x,y,x+FONT_CHAR_WIDTH-1,y+FONT_CHAR_HEIGHT-1);
00232     for(pos=0;pos<FONT_CHAR_HEIGHT;pos++) {
00233       temp = read_font_line(ch, pos);
00234       for(t=0;t<FONT_CHAR_WIDTH;t++) {
00235         if (temp & 0x01) {
00236           sendData(_fgColor);
00237         }
00238         else {
00239           sendData(_bgColor);
00240         }
00241         temp>>=1;
00242       }
00243       y++;
00244     }
00245   }
00246   else { //Draw directly without clearing background
00247     for(pos=0;pos<FONT_CHAR_HEIGHT;pos++) {
00248       temp = read_font_line(ch, pos);
00249       for(t=0;t<FONT_CHAR_WIDTH;t++) {
00250         if (temp & 0x01) {
00251           setAddress(x + t, y + pos, x + t, y + pos);
00252           sendData(_fgColor);
00253           //drawPoint(x + t, y + pos);
00254         }
00255         temp>>=1;
00256       }
00257     }
00258   }
00259 
00260   sbi(_pinCS, _bitmaskCS);
00261 }
00262 
00263 void DmTftBase::drawNumber(uint16_t x, uint16_t y, int num, int digitsToShow, bool leadingZeros) {
00264   bool minus = false;
00265   if (num < 0) {
00266     num = -num;
00267     minus = true;
00268   }
00269   for (int i = 0; i < digitsToShow; i++) {
00270     char c = ' ';
00271     if ((num == 0) && (i > 0)) {
00272       if (leadingZeros) {
00273         c = '0';
00274         if (minus && (i == (digitsToShow-1))) {
00275           c = '-';
00276         }
00277       } else if (minus) {
00278         c = '-';
00279         minus = false;
00280       }
00281     } else {
00282       c = '0' + (num % 10);
00283     }
00284     drawChar(x + FONT_CHAR_WIDTH*(digitsToShow - i - 1), y, c, false);
00285     num = num / 10;
00286   }
00287 }
00288 
00289 void DmTftBase::drawString(uint16_t x, uint16_t y, const char *p) {
00290   while(*p!='\0')
00291   {
00292     if(x > (_width - FONT_CHAR_WIDTH)) {
00293       x = 0;
00294       y += FONT_CHAR_HEIGHT;
00295     }
00296     if(y > (_height - FONT_CHAR_HEIGHT)) {
00297       y = x = 0;
00298     }
00299     drawChar(x, y, *p, false);
00300     x += FONT_CHAR_WIDTH;
00301     p++;
00302   }
00303 }
00304 
00305 void DmTftBase::drawStringCentered(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const char *p) {
00306   int len = strlen(p);
00307   uint16_t tmp = len * FONT_CHAR_WIDTH;
00308   if (tmp <= width) {
00309     x += (width - tmp)/2;
00310   }
00311   if (FONT_CHAR_HEIGHT <= height) {
00312     y += (height - FONT_CHAR_HEIGHT)/2;
00313   }
00314   drawString(x, y, p);
00315 }
00316 
00317 void DmTftBase::drawImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* data) {
00318   const uint16_t* p = data;
00319 
00320   cbi(_pinCS, _bitmaskCS);
00321 
00322   setAddress(x,y,x+width-1,y+height-1);
00323   for (int i = width*height; i > 0; i--) {
00324     sendData(*p);
00325     p++;
00326   }
00327 
00328   sbi(_pinCS, _bitmaskCS);
00329 }
00330 
00331 void DmTftBase::select(){
00332   cbi(_pinCS, _bitmaskCS);
00333 }
00334 
00335 void DmTftBase::unSelect() {
00336   sbi(_pinCS, _bitmaskCS);
00337 }
00338