ST7735 (Red Tab) working on the BBC Microbit

Dependents:   SPI18TFT

Fork of ST7735_TFT by Jonne Valola

Revision:
3:24f890609930
Parent:
2:b460f048ecf5
diff -r b460f048ecf5 -r 24f890609930 ST7735_TFT.cpp
--- 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();
+}