ST7735 (Red Tab) working on the BBC Microbit

Dependents:   SPI18TFT

Fork of ST7735_TFT by Jonne Valola

Files at this revision

API Documentation at this revision

Comitter:
yramesh
Date:
Fri Jan 26 18:03:05 2018 +0000
Parent:
2:b460f048ecf5
Commit message:
ST7735 (Red Tab) working on the BBC Microbit

Changed in this revision

ST7735_TFT.cpp Show annotated file Show diff for this revision Revisions of this file
ST7735_TFT.h Show annotated file Show diff for this revision Revisions of this file
TextDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
TextDisplay.h Show annotated file Show diff for this revision Revisions of this file
--- a/ST7735_TFT.cpp	Wed Jan 24 02:12:24 2018 +0000
+++ b/ST7735_TFT.cpp	Fri Jan 26 18:03:05 2018 +0000
@@ -170,14 +170,13 @@
     return val;
 }
 
-
 void ST7735_TFT::tft_reset() {
     static unsigned short driverCode;
     
     // init SPI
     _spi.format(8,3);                 // 8 bit spi mode 3
     _spi.frequency(16000000);         // 16Mhz SPI clock ... 15Mhz is maximum for display, but it seems to work
-    
+                                      // RY: Changed to 4
     // reset exactly like in Arduino version
     _cs = 0;
     _reset = 1;                       // reset
@@ -293,12 +292,12 @@
   wr_dat(0x00); 
   wr_dat(0x02); 
   wr_dat(0x10); 
-  
-  wr_cmd(ST7735_DISPON); // display ON
-  wait_ms(100);
 
   wr_cmd(ST7735_NORON);  // normal display on
   wait_ms(10);
+  wr_cmd(ST7735_DISPON); // display ON
+  wait_ms(100);  
+/*  
   
   switch (orientation) {
         case 0:
@@ -314,36 +313,34 @@
             wr_reg(0xC8, 0x00A8);
             break;
     }
+*/
     WindowMax ();
 }
 
 
 void ST7735_TFT::pixel(int x, int y, int color) {
+  // setup for data
+    
   if ((x >= width()) || (y >= height())) return;
-
-  window(x,y,x+1,y+1);
-  
-  // setup for data
-   _rs = 1; 
-   _cs = 0;
-  _spi.format(16,3);
-  _spi.write(color);     
-  _cs = 1;
-  _spi.format(8,3);
+  window(x,y,x,y);
+  wr_dat_start();
+  wr_dat(color>>8);
+  wr_dat(color);
+  wr_dat_stop();
 }
 
-void ST7735_TFT::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) {
+void ST7735_TFT::window (unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1) {
   wr_cmd(ST7735_CASET);  // column addr set
-  wr_dat(0x00);
-  wr_dat(x+2);   // XSTART 
-  wr_dat(0x00);
-  wr_dat(x+w+1);   // XEND
+  wr_dat(0x00); //RY Changed this from the GreenTab to RedTab
+  wr_dat(x0);   // XSTART 
+  wr_dat(0x00); //RY Changed this from the GreenTab to RedTab
+  wr_dat(x1);   // XEND
 
   wr_cmd(ST7735_RASET);  // row addr set
-  wr_dat(0x00);
-  wr_dat(y+1);    // YSTART
-  wr_dat(0x00);
-  wr_dat(y+h+1);    // YEND
+  wr_dat(0x00); //RY Changed this from the GreenTab to RedTab
+  wr_dat(y0);    // YSTART
+  wr_dat(0x00); //RY Changed this from the GreenTab to RedTab
+  wr_dat(y1);    // YEND
 
   wr_cmd(ST7735_RAMWR);  // write to RAM
 }
@@ -353,20 +350,10 @@
     window (0, 0, width(),  height());
 }
 
-
 void ST7735_TFT::cls (void) {
-    unsigned int i;
-    WindowMax();
-    wr_dat_start();
-    _spi.format(16,3);
-    for (i = 0; i < ( (width()+1) * (height()+3)); i++) {
-        _spi.write(_background);    
-    }
-    _spi.format(8,3);
-    wr_dat_stop();
+    fillrect(0, 0, width(),  height(), _background);
 }
 
-
 void ST7735_TFT::circle(int x0, int y0, int r, int color) {
 
     int draw_x0, draw_y0;
@@ -480,40 +467,39 @@
         circle(x,y,i,color);
 }
 
-
+void ST7735_TFT::hline(int x, int y, int w, int color) {
+  int hi = color >> 8, lo = color;
 
-void ST7735_TFT::hline(int x0, int x1, int y, int color) {
-    int w;
-    w = x1 - x0 + 1;
-    window(x0,y,w,1);
-    wr_cmd(0x2C);
-    wr_dat_start();
-    for (int x=0; x<w; x++) {
-        _spi.write(color);
-        _spi.write(color >> 8);
-    }
+  // Rudimentary clipping
+  if((x >= width()) || (y >= height())) return;
+  if((x+w-1) >= width())  w = width()-x;
+  window(x, y, x+w-1, y);
+
+  while (w--) {
+    wr_dat(hi);
+    wr_dat(lo);
+  }
     wr_dat_stop();
     return;
 }
 
-
+void ST7735_TFT::vline(int x, int y, int h, int color) {
+  int hi = color >> 8, lo = color;
 
-void ST7735_TFT::vline(int x, int y0, int y1, int color) {
-    int h;
-    h = y1 - y0 + 1;
-    window(x,y0,1,h);
-    wr_cmd(0x2C);
-    wr_dat_start();
-    for (int y=0; y<h; y++) {
-        _spi.write(color);
-        _spi.write(color >> 8);
-    }
-    wr_dat_stop();
+  // Rudimentary clipping
+  if((x >= width()) || (y >= height())) return;
+  if((y+h-1) >= height()) h = height()-y;
+  window(x, y, x, y+h-1);
+
+  while (h--) {
+    wr_dat(hi);
+    wr_dat(lo);
+  }
+
+  wr_dat_stop();
     return;
 }
 
-
-
 void ST7735_TFT::line(int x0, int y0, int x1, int y1, int color) {
     WindowMax();
     int   dx = 0, dy = 0;
@@ -584,9 +570,6 @@
     return;
 }
 
-
-
-
 void ST7735_TFT::rect(int x0, int y0, int x1, int y1, int color) {
 
     if (x1 > x0) hline(x0,x1,y0,color);
@@ -604,211 +587,149 @@
     return;
 }
 
-
+void ST7735_TFT::fillrect(int x, int y, int w, int h, int color) {
+  int hi = color >> 8, lo = color;
 
-void ST7735_TFT::fillrect(int x0, int y0, int x1, int y1, int color) {
+  // rudimentary clipping (drawChar w/big text requires this)
+  if((x >= width()) || (y >= height())) return;
+  if((x + w - 1) >= width())  w = width()  - x;
+  if((y + h - 1) >= height()) h = height() - y;
 
-    int h = y1 - y0 + 1;
-    int w = x1 - x0 + 1;
-    int pixel = h * w;
-    window(x0,y0,w,h);
-    wr_cmd(0x2C);
-    wr_dat_start();
-    for (int p=0; p<pixel; p++) {
-        _spi.write(color);
-        _spi.write(color >> 8);
+  window(x, y, x+w-1, y+h-1);
+  for(y=h; y>0; y--) {
+    for(x=w; x>0; x--) {
+      wr_dat(hi);
+      wr_dat(lo);
     }
-    wr_dat_stop();
-    return;
+  }
+  wr_dat_stop();
 }
 
-
-
 void ST7735_TFT::locate(int x, int y) {
     char_x = x;
     char_y = y;
 }
 
-
-
 int ST7735_TFT::columns() {
     return width() / font[1];
 }
 
-
-
 int ST7735_TFT::rows() {
     return height() / font[2];
 }
 
-
-
-int ST7735_TFT::_putc(int value) {
-    if (value == '\n') {    // new line
-        char_x = 0;
-        char_y = char_y + font[2];
-        if (char_y >= height() - font[2]) {
-            char_y = 0;
-        }
-    } else {
-        character(char_x, char_y, value);
-     }
-    return value;
-}
-
-
-
-
-void ST7735_TFT::character(int x, int y, int c) {
-    unsigned int hor,vert,offset,bpl,j,i,b;
-    unsigned char* zeichen;
-    unsigned char z,w;
-
-    if ((c < 31) || (c > 127)) return;   // test char range
-
-    // read font parameter from start of array
-    offset = font[0];                    // bytes / char
-    hor = font[1];                       // get hor size of font
-    vert = font[2];                      // get vert size of font
-    bpl = font[3];                       // bytes per line
-
-    if (char_x + hor > width()) {
-        char_x = 0;
-        char_y = char_y + vert;
-       if (char_y >= height() - font[2]) {
-            char_y = 0;
-        }
+int ST7735_TFT::_putc(int ch) {
+  if((ch == 10) || (ch == 13) || (ch == 27)){
+    char_y++; char_x=0;
+    if(char_y>15){
+      char_y = 0;
     }
-
-    window(char_x, char_y,hor,vert); // char box
-    wr_cmd(0x2C);
-    wr_dat_start();
-    zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
-    w = zeichen[0];                          // width of actual char
-    _spi.format(16,3);                       // pixel are 16 bit
-
-    for (j=0; j<vert; j++) {  //  vert line
-        for (i=0; i<hor; i++) {   //  horz line
-            z =  zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
-            b = 1 << (j & 0x07);
-            if (( z & b ) == 0x00) {
-                _spi.write(_background);
-            } else {
-                _spi.write(_foreground);
-            }
-        }
-    }
-    _spi.format(8,3);                      // 8 bit
-    wr_dat_stop();
-    if ((w + 2) < hor) {                   // x offset to next char
-        char_x += w + 2;
-    } else char_x += hor;
-}
-
-
-
-
-
-void ST7735_TFT::set_font(unsigned char* f) {
-    font = f;
+    drawstring(0,char_y,"                     ");
+    return 1;
+  }
+  character(char_x*6,char_y*10,ch, 1);
+  char_x++;
+  if(char_x>20){
+    char_x = 20;
+    character(char_x*6,char_y*10,'*', 1);
+  }
+  return 1;
 }
 
 
+void ST7735_TFT::character(int x, int y, int c, int size) {
+  int line; // vertical column of pixels of character in font
+  int i, j;
+  if((x >= width())            || // Clip right
+     (y >= height())           || // Clip bottom
+     ((x + 6 * size - 1) < 0) || // Clip left
+     ((y + 8 * size - 1) < 0))   // Clip top
+    return;
 
-void ST7735_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) {
-    unsigned int    i,j,value;
-    unsigned short *bitmap_ptr = (unsigned short *)bitmap;
-    window(x, y, w, h);
-    wr_cmd(0x2C);
-    wr_dat_start();
-    for (j = 0; j < h; j++) {        //Lines
-        for (i = 0; i < w; i++) {     // copy pixel data to TFT
-            _spi.write(*bitmap_ptr);    // one line
-            _spi.write(*bitmap_ptr >> 8);  
-            bitmap_ptr++;
+  for (i=0; i<6; i++ ) {
+    if (i == 5)
+      line = 0x0;
+    else
+      line = Font[(c*5)+i];
+    for (j = 0; j<8; j++) {
+      if (line & 0x1) {
+        if (size == 1) // default size
+          pixel(x+i, y+j,_foreground);
+        else {  // big size
+          fillrect(x+(i*size), y+(j*size), size, size, _foreground);
+        }
+      } else if (_background != _foreground) {
+        if (size == 1) // default size
+          pixel(x+i, y+j, _background);
+        else {  // big size
+          fillrect(x+i*size, y+j*size, size, size, _background);
         }
+      }
+      line >>= 1;
     }
-    wr_dat_stop();
+  }
+}
+
+void ST7735_TFT::drawstring(int x, int y, char *pt) {
+  int count = 0;
+  if(y>15) return;
+  while(*pt){
+    character(x*6, y*10, *pt, 1);
+    pt++;
+    x = x+1;
+    if(x>20) return;  // number of characters printed
+    count++;
+  }
+  return;  // number of characters printed
 }
 
-
-int ST7735_TFT::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP) {
-// BEWARE !
-// NOT TESTED
-#define OffsetPixelWidth    18
-#define OffsetPixelHeigh    22
-#define OffsetFileSize      34
-#define OffsetPixData       10
-#define OffsetBPP           28
-
-    char filename[50];
-    unsigned char BMP_Header[54];
-    unsigned short BPP_t;
-    unsigned int PixelWidth,PixelHeigh,start_data;
-    unsigned int    i,off;
-    int padd,j;
-    unsigned short *line;
-
-    // get the filename
-//    LocalFileSystem local("local");
-    sprintf(&filename[0],"/local/");
-    i=7;
-    while (*Name_BMP!='\0') {
-        filename[i++]=*Name_BMP++;
-    }
-    FILE *Image = fopen((const char *)&filename[0], "r");  // open the bmp file
-    if (!Image) {
-        return(0);      // error file not found !
-    }
-
-    fread(&BMP_Header[0],1,54,Image);      // get the BMP Header
-
-    if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) {  // check magic byte
-        fclose(Image);
-        return(-1);     // error no BMP file
-    }
+void ST7735_TFT::Bitmap( short x,  short y,  short w, short h, const unsigned short *image) {
+  short skipC = 0;                   // non-zero if columns need to be skipped due to clipping
+  short originalWidth = w;           // save this value; even if not all columns fit on the screen, the image is still this width in ROM
+  int i = w*(h - 1);
 
-    BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
-    if (BPP_t != 0x0010) {
-        fclose(Image);
-        return(-2);     // error no 16 bit BMP
-    }
-
-    PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
-    PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
-    if (PixelHeigh > height() + y || PixelWidth > width() + x) {
-        fclose(Image);
-        return(-3);      // to big
-    }
-
-    start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
-
-    line = (unsigned short *) malloc (PixelWidth); // we need a buffer for a line
-    if (line == NULL) {
-        return(-4);         // error no memory
-    }
+  if((x >= width()) || ((y - h + 1) >= height()) || ((x + w) <= 0) || (y < 0)){
+    return;                             // image is totally off the screen, do nothing
+  }
+  if((w > width()) || (h > height())){    // image is too wide for the screen, do nothing
+    //***This isn't necessarily a fatal error, but it makes the
+    //following logic much more complicated, since you can have
+    //an image that exceeds multiple boundaries and needs to be
+    //clipped on more than one side.
+    return;
+  }
+  if((x + w - 1) >= width()){            // image exceeds right of screen
+    skipC = (x + w) - width();           // skip cut off columns
+    w = width() - x;
+  }
+  if((y - h + 1) < 0){                  // image exceeds top of screen
+    i = i - (h - y - 1)*originalWidth;  // skip the last cut off rows
+    h = y + 1;
+  }
+  if(x < 0){                            // image exceeds left of screen
+    w = w + x;
+    skipC = -1*x;                       // skip cut off columns
+    i = i - x;                          // skip the first cut off columns
+    x = 0;
+  }
+  if(y >= height()){                     // image exceeds bottom of screen
+    h = h - (y - height() + 1);
+    y = height() - 1;
+  }
 
-    // the lines are padded to multiple of 4 bytes
-    padd = -1;
-    do {
-        padd ++;
-    } while ((PixelWidth * 2 + padd)%4 != 0);
+  window(x, y-h+1, x+w-1, y);
 
-    window(x, y,PixelWidth,PixelHeigh);
-    wr_cmd(0x2C);
-    wr_dat_start();
-    _spi.format(16,3);    
-    for (j = PixelHeigh - 1; j >= 0; j--) {               //Lines bottom up
-        off = j * (PixelWidth * 2 + padd) + start_data;   // start of line
-        fseek(Image, off ,SEEK_SET);
-        fread(line,1,PixelWidth * 2,Image);       // read a line - slow !
-        for (i = 0; i < PixelWidth; i++) {        // copy pixel data to TFT
-            _spi.write(line[i]);                  // one 16 bit pixel
-        } 
+  for(y=0; y<h; y=y+1){
+    for(x=0; x<w; x=x+1){
+                                        // send the top 8 bits
+      wr_dat((unsigned char)(image[i] >> 8));
+                                        // send the bottom 8 bits
+      wr_dat((unsigned char)(image[i]));
+      i = i + 1;                        // go to the next pixel
     }
-    _spi.format(8,3);
-    wr_dat_stop();
-    free (line);
-    fclose(Image);
-    return(1);
-}
\ No newline at end of file
+    i = i + skipC;
+    i = i - 2*originalWidth;
+  }
+
+  wr_dat_stop();
+}
--- a/ST7735_TFT.h	Wed Jan 24 02:12:24 2018 +0000
+++ b/ST7735_TFT.h	Fri Jan 26 18:03:05 2018 +0000
@@ -74,25 +74,275 @@
 #define ST7735_GMCTRN1 0xE1
 
 /* some RGB color definitions                                                 */
-#define Black           0x0000      /*   0,   0,   0 */
-#define Navy            0x000F      /*   0,   0, 128 */
-#define DarkGreen       0x03E0      /*   0, 128,   0 */
-#define DarkCyan        0x03EF      /*   0, 128, 128 */
-#define Maroon          0x7800      /* 128,   0,   0 */
-#define Purple          0x780F      /* 128,   0, 128 */
-#define Olive           0x7BE0      /* 128, 128,   0 */
-#define LightGrey       0xC618      /* 192, 192, 192 */
-#define DarkGrey        0x7BEF      /* 128, 128, 128 */
-#define Blue            0x001F      /*   0,   0, 255 */
-#define Green           0x07E0      /*   0, 255,   0 */
-#define Cyan            0x07FF      /*   0, 255, 255 */
-#define Red             0xF800      /* 255,   0,   0 */
-#define Magenta         0xF81F      /* 255,   0, 255 */
-#define Yellow          0xFFE0      /* 255, 255,   0 */
-#define White           0xFFFF      /* 255, 255, 255 */
-#define Orange          0xFD20      /* 255, 165,   0 */
-#define GreenYellow     0xAFE5      /* 173, 255,  47 */
+#define ST7735_BLACK   0x0000
+#define ST7735_BLUE    0xF800
+#define ST7735_RED     0x001F
+#define ST7735_GREEN   0x07E0
+#define ST7735_CYAN    0xFFE0
+#define ST7735_MAGENTA 0xF81F
+#define ST7735_YELLOW  0x07FF
+#define ST7735_WHITE   0xFFFF
+
 
+// standard ascii 5x7 font
+// originally from glcdfont.c from Adafruit project
+static const unsigned char Font[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
+  0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
+  0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
+  0x18, 0x3C, 0x7E, 0x3C, 0x18,
+  0x1C, 0x57, 0x7D, 0x57, 0x1C,
+  0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
+  0x00, 0x18, 0x3C, 0x18, 0x00,
+  0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
+  0x00, 0x18, 0x24, 0x18, 0x00,
+  0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
+  0x30, 0x48, 0x3A, 0x06, 0x0E,
+  0x26, 0x29, 0x79, 0x29, 0x26,
+  0x40, 0x7F, 0x05, 0x05, 0x07,
+  0x40, 0x7F, 0x05, 0x25, 0x3F,
+  0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
+  0x7F, 0x3E, 0x1C, 0x1C, 0x08,
+  0x08, 0x1C, 0x1C, 0x3E, 0x7F,
+  0x14, 0x22, 0x7F, 0x22, 0x14,
+  0x5F, 0x5F, 0x00, 0x5F, 0x5F,
+  0x06, 0x09, 0x7F, 0x01, 0x7F,
+  0x00, 0x66, 0x89, 0x95, 0x6A,
+  0x60, 0x60, 0x60, 0x60, 0x60,
+  0x94, 0xA2, 0xFF, 0xA2, 0x94,
+  0x08, 0x04, 0x7E, 0x04, 0x08,
+  0x10, 0x20, 0x7E, 0x20, 0x10,
+  0x08, 0x08, 0x2A, 0x1C, 0x08,
+  0x08, 0x1C, 0x2A, 0x08, 0x08,
+  0x1E, 0x10, 0x10, 0x10, 0x10,
+  0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
+  0x30, 0x38, 0x3E, 0x38, 0x30,
+  0x06, 0x0E, 0x3E, 0x0E, 0x06,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x5F, 0x00, 0x00,
+  0x00, 0x07, 0x00, 0x07, 0x00,
+  0x14, 0x7F, 0x14, 0x7F, 0x14,
+  0x24, 0x2A, 0x7F, 0x2A, 0x12,
+  0x23, 0x13, 0x08, 0x64, 0x62,
+  0x36, 0x49, 0x56, 0x20, 0x50,
+  0x00, 0x08, 0x07, 0x03, 0x00,
+  0x00, 0x1C, 0x22, 0x41, 0x00,
+  0x00, 0x41, 0x22, 0x1C, 0x00,
+  0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
+  0x08, 0x08, 0x3E, 0x08, 0x08,
+  0x00, 0x80, 0x70, 0x30, 0x00,
+  0x08, 0x08, 0x08, 0x08, 0x08,
+  0x00, 0x00, 0x60, 0x60, 0x00,
+  0x20, 0x10, 0x08, 0x04, 0x02,
+  0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
+  0x00, 0x42, 0x7F, 0x40, 0x00, // 1
+  0x72, 0x49, 0x49, 0x49, 0x46, // 2
+  0x21, 0x41, 0x49, 0x4D, 0x33, // 3
+  0x18, 0x14, 0x12, 0x7F, 0x10, // 4
+  0x27, 0x45, 0x45, 0x45, 0x39, // 5
+  0x3C, 0x4A, 0x49, 0x49, 0x31, // 6
+  0x41, 0x21, 0x11, 0x09, 0x07, // 7
+  0x36, 0x49, 0x49, 0x49, 0x36, // 8
+  0x46, 0x49, 0x49, 0x29, 0x1E, // 9
+  0x00, 0x00, 0x14, 0x00, 0x00,
+  0x00, 0x40, 0x34, 0x00, 0x00,
+  0x00, 0x08, 0x14, 0x22, 0x41,
+  0x14, 0x14, 0x14, 0x14, 0x14,
+  0x00, 0x41, 0x22, 0x14, 0x08,
+  0x02, 0x01, 0x59, 0x09, 0x06,
+  0x3E, 0x41, 0x5D, 0x59, 0x4E,
+  0x7C, 0x12, 0x11, 0x12, 0x7C, // A
+  0x7F, 0x49, 0x49, 0x49, 0x36, // B
+  0x3E, 0x41, 0x41, 0x41, 0x22, // C
+  0x7F, 0x41, 0x41, 0x41, 0x3E, // D
+  0x7F, 0x49, 0x49, 0x49, 0x41, // E
+  0x7F, 0x09, 0x09, 0x09, 0x01, // F
+  0x3E, 0x41, 0x41, 0x51, 0x73, // G
+  0x7F, 0x08, 0x08, 0x08, 0x7F, // H
+  0x00, 0x41, 0x7F, 0x41, 0x00, // I
+  0x20, 0x40, 0x41, 0x3F, 0x01, // J
+  0x7F, 0x08, 0x14, 0x22, 0x41, // K
+  0x7F, 0x40, 0x40, 0x40, 0x40, // L
+  0x7F, 0x02, 0x1C, 0x02, 0x7F, // M
+  0x7F, 0x04, 0x08, 0x10, 0x7F, // N
+  0x3E, 0x41, 0x41, 0x41, 0x3E, // O
+  0x7F, 0x09, 0x09, 0x09, 0x06, // P
+  0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
+  0x7F, 0x09, 0x19, 0x29, 0x46, // R
+  0x26, 0x49, 0x49, 0x49, 0x32, // S
+  0x03, 0x01, 0x7F, 0x01, 0x03, // T
+  0x3F, 0x40, 0x40, 0x40, 0x3F, // U
+  0x1F, 0x20, 0x40, 0x20, 0x1F, // V
+  0x3F, 0x40, 0x38, 0x40, 0x3F, // W
+  0x63, 0x14, 0x08, 0x14, 0x63, // X
+  0x03, 0x04, 0x78, 0x04, 0x03, // Y
+  0x61, 0x59, 0x49, 0x4D, 0x43, // Z
+  0x00, 0x7F, 0x41, 0x41, 0x41,
+  0x02, 0x04, 0x08, 0x10, 0x20,
+  0x00, 0x41, 0x41, 0x41, 0x7F,
+  0x04, 0x02, 0x01, 0x02, 0x04,
+  0x40, 0x40, 0x40, 0x40, 0x40,
+  0x00, 0x03, 0x07, 0x08, 0x00,
+  0x20, 0x54, 0x54, 0x78, 0x40, // a
+  0x7F, 0x28, 0x44, 0x44, 0x38, // b
+  0x38, 0x44, 0x44, 0x44, 0x28, // c
+  0x38, 0x44, 0x44, 0x28, 0x7F, // d
+  0x38, 0x54, 0x54, 0x54, 0x18, // e
+  0x00, 0x08, 0x7E, 0x09, 0x02, // f
+  0x18, 0xA4, 0xA4, 0x9C, 0x78, // g
+  0x7F, 0x08, 0x04, 0x04, 0x78, // h
+  0x00, 0x44, 0x7D, 0x40, 0x00, // i
+  0x20, 0x40, 0x40, 0x3D, 0x00, // j
+  0x7F, 0x10, 0x28, 0x44, 0x00, // k
+  0x00, 0x41, 0x7F, 0x40, 0x00, // l
+  0x7C, 0x04, 0x78, 0x04, 0x78, // m
+  0x7C, 0x08, 0x04, 0x04, 0x78, // n
+  0x38, 0x44, 0x44, 0x44, 0x38, // o
+  0xFC, 0x18, 0x24, 0x24, 0x18, // p
+  0x18, 0x24, 0x24, 0x18, 0xFC, // q
+  0x7C, 0x08, 0x04, 0x04, 0x08, // r
+  0x48, 0x54, 0x54, 0x54, 0x24, // s
+  0x04, 0x04, 0x3F, 0x44, 0x24, // t
+  0x3C, 0x40, 0x40, 0x20, 0x7C, // u
+  0x1C, 0x20, 0x40, 0x20, 0x1C, // v
+  0x3C, 0x40, 0x30, 0x40, 0x3C, // w
+  0x44, 0x28, 0x10, 0x28, 0x44, // x
+  0x4C, 0x90, 0x90, 0x90, 0x7C, // y
+  0x44, 0x64, 0x54, 0x4C, 0x44, // z
+  0x00, 0x08, 0x36, 0x41, 0x00,
+  0x00, 0x00, 0x77, 0x00, 0x00,
+  0x00, 0x41, 0x36, 0x08, 0x00,
+  0x02, 0x01, 0x02, 0x04, 0x02,
+  0x3C, 0x26, 0x23, 0x26, 0x3C,
+  0x1E, 0xA1, 0xA1, 0x61, 0x12,
+  0x3A, 0x40, 0x40, 0x20, 0x7A,
+  0x38, 0x54, 0x54, 0x55, 0x59,
+  0x21, 0x55, 0x55, 0x79, 0x41,
+  0x21, 0x54, 0x54, 0x78, 0x41,
+  0x21, 0x55, 0x54, 0x78, 0x40,
+  0x20, 0x54, 0x55, 0x79, 0x40,
+  0x0C, 0x1E, 0x52, 0x72, 0x12,
+  0x39, 0x55, 0x55, 0x55, 0x59,
+  0x39, 0x54, 0x54, 0x54, 0x59,
+  0x39, 0x55, 0x54, 0x54, 0x58,
+  0x00, 0x00, 0x45, 0x7C, 0x41,
+  0x00, 0x02, 0x45, 0x7D, 0x42,
+  0x00, 0x01, 0x45, 0x7C, 0x40,
+  0xF0, 0x29, 0x24, 0x29, 0xF0,
+  0xF0, 0x28, 0x25, 0x28, 0xF0,
+  0x7C, 0x54, 0x55, 0x45, 0x00,
+  0x20, 0x54, 0x54, 0x7C, 0x54,
+  0x7C, 0x0A, 0x09, 0x7F, 0x49,
+  0x32, 0x49, 0x49, 0x49, 0x32,
+  0x32, 0x48, 0x48, 0x48, 0x32,
+  0x32, 0x4A, 0x48, 0x48, 0x30,
+  0x3A, 0x41, 0x41, 0x21, 0x7A,
+  0x3A, 0x42, 0x40, 0x20, 0x78,
+  0x00, 0x9D, 0xA0, 0xA0, 0x7D,
+  0x39, 0x44, 0x44, 0x44, 0x39,
+  0x3D, 0x40, 0x40, 0x40, 0x3D,
+  0x3C, 0x24, 0xFF, 0x24, 0x24,
+  0x48, 0x7E, 0x49, 0x43, 0x66,
+  0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
+  0xFF, 0x09, 0x29, 0xF6, 0x20,
+  0xC0, 0x88, 0x7E, 0x09, 0x03,
+  0x20, 0x54, 0x54, 0x79, 0x41,
+  0x00, 0x00, 0x44, 0x7D, 0x41,
+  0x30, 0x48, 0x48, 0x4A, 0x32,
+  0x38, 0x40, 0x40, 0x22, 0x7A,
+  0x00, 0x7A, 0x0A, 0x0A, 0x72,
+  0x7D, 0x0D, 0x19, 0x31, 0x7D,
+  0x26, 0x29, 0x29, 0x2F, 0x28,
+  0x26, 0x29, 0x29, 0x29, 0x26,
+  0x30, 0x48, 0x4D, 0x40, 0x20,
+  0x38, 0x08, 0x08, 0x08, 0x08,
+  0x08, 0x08, 0x08, 0x08, 0x38,
+  0x2F, 0x10, 0xC8, 0xAC, 0xBA,
+  0x2F, 0x10, 0x28, 0x34, 0xFA,
+  0x00, 0x00, 0x7B, 0x00, 0x00,
+  0x08, 0x14, 0x2A, 0x14, 0x22,
+  0x22, 0x14, 0x2A, 0x14, 0x08,
+  0xAA, 0x00, 0x55, 0x00, 0xAA,
+  0xAA, 0x55, 0xAA, 0x55, 0xAA,
+  0x00, 0x00, 0x00, 0xFF, 0x00,
+  0x10, 0x10, 0x10, 0xFF, 0x00,
+  0x14, 0x14, 0x14, 0xFF, 0x00,
+  0x10, 0x10, 0xFF, 0x00, 0xFF,
+  0x10, 0x10, 0xF0, 0x10, 0xF0,
+  0x14, 0x14, 0x14, 0xFC, 0x00,
+  0x14, 0x14, 0xF7, 0x00, 0xFF,
+  0x00, 0x00, 0xFF, 0x00, 0xFF,
+  0x14, 0x14, 0xF4, 0x04, 0xFC,
+  0x14, 0x14, 0x17, 0x10, 0x1F,
+  0x10, 0x10, 0x1F, 0x10, 0x1F,
+  0x14, 0x14, 0x14, 0x1F, 0x00,
+  0x10, 0x10, 0x10, 0xF0, 0x00,
+  0x00, 0x00, 0x00, 0x1F, 0x10,
+  0x10, 0x10, 0x10, 0x1F, 0x10,
+  0x10, 0x10, 0x10, 0xF0, 0x10,
+  0x00, 0x00, 0x00, 0xFF, 0x10,
+  0x10, 0x10, 0x10, 0x10, 0x10,
+  0x10, 0x10, 0x10, 0xFF, 0x10,
+  0x00, 0x00, 0x00, 0xFF, 0x14,
+  0x00, 0x00, 0xFF, 0x00, 0xFF,
+  0x00, 0x00, 0x1F, 0x10, 0x17,
+  0x00, 0x00, 0xFC, 0x04, 0xF4,
+  0x14, 0x14, 0x17, 0x10, 0x17,
+  0x14, 0x14, 0xF4, 0x04, 0xF4,
+  0x00, 0x00, 0xFF, 0x00, 0xF7,
+  0x14, 0x14, 0x14, 0x14, 0x14,
+  0x14, 0x14, 0xF7, 0x00, 0xF7,
+  0x14, 0x14, 0x14, 0x17, 0x14,
+  0x10, 0x10, 0x1F, 0x10, 0x1F,
+  0x14, 0x14, 0x14, 0xF4, 0x14,
+  0x10, 0x10, 0xF0, 0x10, 0xF0,
+  0x00, 0x00, 0x1F, 0x10, 0x1F,
+  0x00, 0x00, 0x00, 0x1F, 0x14,
+  0x00, 0x00, 0x00, 0xFC, 0x14,
+  0x00, 0x00, 0xF0, 0x10, 0xF0,
+  0x10, 0x10, 0xFF, 0x10, 0xFF,
+  0x14, 0x14, 0x14, 0xFF, 0x14,
+  0x10, 0x10, 0x10, 0x1F, 0x00,
+  0x00, 0x00, 0x00, 0xF0, 0x10,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+  0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xFF, 0xFF,
+  0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+  0x38, 0x44, 0x44, 0x38, 0x44,
+  0x7C, 0x2A, 0x2A, 0x3E, 0x14,
+  0x7E, 0x02, 0x02, 0x06, 0x06,
+  0x02, 0x7E, 0x02, 0x7E, 0x02,
+  0x63, 0x55, 0x49, 0x41, 0x63,
+  0x38, 0x44, 0x44, 0x3C, 0x04,
+  0x40, 0x7E, 0x20, 0x1E, 0x20,
+  0x06, 0x02, 0x7E, 0x02, 0x02,
+  0x99, 0xA5, 0xE7, 0xA5, 0x99,
+  0x1C, 0x2A, 0x49, 0x2A, 0x1C,
+  0x4C, 0x72, 0x01, 0x72, 0x4C,
+  0x30, 0x4A, 0x4D, 0x4D, 0x30,
+  0x30, 0x48, 0x78, 0x48, 0x30,
+  0xBC, 0x62, 0x5A, 0x46, 0x3D,
+  0x3E, 0x49, 0x49, 0x49, 0x00,
+  0x7E, 0x01, 0x01, 0x01, 0x7E,
+  0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
+  0x44, 0x44, 0x5F, 0x44, 0x44,
+  0x40, 0x51, 0x4A, 0x44, 0x40,
+  0x40, 0x44, 0x4A, 0x51, 0x40,
+  0x00, 0x00, 0xFF, 0x01, 0x03,
+  0xE0, 0x80, 0xFF, 0x00, 0x00,
+  0x08, 0x08, 0x6B, 0x6B, 0x08,
+  0x36, 0x12, 0x36, 0x24, 0x36,
+  0x06, 0x0F, 0x09, 0x0F, 0x06,
+  0x00, 0x00, 0x18, 0x18, 0x00,
+  0x00, 0x00, 0x10, 0x10, 0x00,
+  0x30, 0x40, 0xFF, 0x01, 0x01,
+  0x00, 0x1F, 0x01, 0x01, 0x1E,
+  0x00, 0x19, 0x1D, 0x17, 0x12,
+  0x00, 0x3C, 0x3C, 0x3C, 0x3C,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+};
 class ST7735_TFT : public GraphicsDisplay {
  public:
 
@@ -227,9 +477,11 @@
    * @param y y-position
    * @param c char to print
    *
-   */    
-  virtual void character(int x, int y, int c);
-    
+   */  
+  virtual void character(int x, int y, int c, int size);
+
+  virtual void drawstring(int x, int y, char *pt);
+  
   /** paint a bitmap on the TFT 
    *
    * @param x,y : upper left corner 
@@ -248,27 +500,8 @@
    *   cast the pointer to (unsigned char *) :
    *   tft.Bitmap(10,40,309,50,(unsigned char *)scala);
    */    
-  void Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap);
-    
+  void Bitmap(short x,  short y,  short w, short h, const unsigned short *bitmap);
     
-   /** paint a 16 bit BMP from local filesytem on the TFT (slow) 
-   *
-   * @param x,y : upper left corner 
-   * @param *Name_BMP name of the BMP file
-   * @returns 1 if bmp file was found and painted
-   * @returns -1 if bmp file was found not found
-   * @returns -2 if bmp file is not 16bit
-   * @returns -3 if bmp file is to big for screen 
-   * @returns -4 if buffer malloc go wrong
-   *
-   *   bitmap format: 16 bit R5 G6 B5
-   * 
-   *   use Gimp to create / load , save as BMP, option 16 bit R5 G6 B5
-   *   copy to internal file system            
-   * 
-   */      
-    
-  int BMP_16(unsigned int x, unsigned int y, const char *Name_BMP);  
     
    /** Read an area from the LCD RAM to MCU RAM
    *
@@ -280,20 +513,6 @@
 
   void read_area(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *buffer);  
     
-  /** select the font to use
-   *
-   * @param f pointer to font array 
-   *                                                                              
-   *   font array can created with GLCD Font Creator from http://www.mikroe.com
-   *   you have to add 4 parameter at the beginning of the font array to use: 
-   *   - the number of byte / char
-   *   - the vertial size in pixel
-   *   - the horizontal size in pixel
-   *   - the number of byte per vertical line
-   *   you also have to change the array to char[]
-   *
-   */  
-  void set_font(unsigned char* f);
    
   /** Set the orientation of the screen
    *  x,y: 0,0 is always top left 
@@ -313,31 +532,31 @@
 
   /** draw a horizontal line
    *
-   * @param x0 horizontal start
-   * @param x1 horizontal stop
-   * @param y vertical position
+   * @param x coords
+   * @param y 
+   * @param w how wide
    * @param color 16 bit color                                               
    *
    */
-  void hline(int x0, int x1, int y, int colour);
+  void hline(int x, int y, int w, int color);
     
   /** draw a vertical line
    *
-   * @param x horizontal position
-   * @param y0 vertical start 
-   * @param y1 vertical stop
+   * @param  x coords
+   * @param  y 
+   * @param  h how high
    * @param color 16 bit color
    */
-  void vline(int y0, int y1, int x, int colour);
+  void vline(int x, int y, int h, int color);
     
   /** Set draw window region
    *
-   * @param x horizontal position
-   * @param y vertical position
-   * @param w window width in pixel
-   * @param h window height in pixels
+   * @param x0 horizontal position (top left)
+   * @param y0 vertical position (top left)
+   * @param x1 window width in pixel (bottom right)
+   * @param y1 window height in pixels (bottom right)
    */    
-  void window (unsigned int x, unsigned int y, unsigned int w, unsigned int h);
+  void window (unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1);
     
   /** Set draw window region to whole screen
    *
--- a/TextDisplay.cpp	Wed Jan 24 02:12:24 2018 +0000
+++ b/TextDisplay.cpp	Fri Jan 26 18:03:05 2018 +0000
@@ -24,7 +24,7 @@
             _row = 0;
         }
     } else {
-        character(_column, _row, value);
+        character(_column, _row, value, 1);
         _column++;
         if(_column >= columns()) {
             _column = 0;
--- a/TextDisplay.h	Wed Jan 24 02:12:24 2018 +0000
+++ b/TextDisplay.h	Fri Jan 26 18:03:05 2018 +0000
@@ -34,8 +34,9 @@
      * @param  row where character must be written
      * @param c the character to be written to the TextDisplay
      */
-    virtual void character(int column, int row, int c) = 0;
+    virtual void character(int column, int row, int c, int size) = 0;
 
+    virtual void drawstring(int x, int y, char *pt) = 0;
     /** return number if rows on TextDisplay
      * @result number of rows
      */