Anonymous avatar Anonymous committed c498da7

- added Adafruit TFTLCD library

Comments (0)

Files changed (16)

Adafruit_TFTLCD-Library/Adafruit_TFTLCD.cpp

+#include "Adafruit_TFTLCD.h"
+
+// Graphics library by ladyada/adafruit with init code from Rossum 
+// MIT license
+
+static volatile uint8_t *wrportreg;
+
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+// special defines for the dataport
+
+// for mega & shield usage, we just hardcoded it (its messy)
+ #define DATAPORT1 PORTD
+ #define DATAPIN1 PIND
+ #define DATADDR1 DDRD
+
+ #define DATAPORT2 PORTB
+ #define DATAPIN2 PINB
+ #define DATADDR2 DDRB
+
+ #define DATA1_MASK 0xD0
+ #define DATA2_MASK 0x2F
+
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__)
+ #define WRPORT PORTC
+ #define RDPORT PORTC
+ #define CSPORT PORTC
+ #define CDPORT PORTC
+ #define WRPIN  1
+ #define CDPIN  2
+ #define CSPIN  3
+ #define RDPIN  0
+#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) 
+ #define WRPORT PORTF
+ #define RDPORT PORTF
+ #define CSPORT PORTF
+ #define CDPORT PORTF
+ #define WRPIN  1
+ #define CDPIN  2
+ #define CSPIN  3
+ #define RDPIN  0
+#endif 
+
+
+#else
+ // for the breakout board tutorial, two ports are used :/
+ #define DATAPORT1 PORTD
+ #define DATAPIN1  PIND
+ #define DATADDR1  DDRD
+
+ #define DATAPORT2 PORTB
+ #define DATAPIN2  PINB
+ #define DATADDR2  DDRB
+
+ #define DATA1_MASK 0xFC  // top 6 bits
+ #define DATA2_MASK 0x03  // bottom 2 bits
+
+ // Megas have lots of pins, we'll use port A - all 8 bits in a row - pins 22 thru 29
+ #define MEGA_DATAPORT PORTA
+ #define MEGA_DATAPIN  PINA
+ #define MEGA_DATADDR  DDRA
+#endif
+
+
+#include <avr/pgmspace.h>
+#include "pins_arduino.h"
+#include "wiring_private.h"
+
+
+void Adafruit_TFTLCD::goTo(int x, int y) {
+  if (driver == 0x9325 || driver == 0x9328) {
+    writeRegister16(0x0020, x);     // GRAM Address Set (Horizontal Address) (R20h)
+    writeRegister16(0x0021, y);     // GRAM Address Set (Vertical Address) (R21h)
+    writeCommand(0x0022);            // Write Data to GRAM (R22h)
+  } 
+  if (driver == 0x7575) {
+    writeRegister8(HX8347G_COLADDRSTART2, x>>8);
+    writeRegister8(HX8347G_COLADDRSTART1, x);
+    writeRegister8(HX8347G_ROWADDRSTART2, y>>8);
+    writeRegister8(HX8347G_ROWADDRSTART1, y);
+
+    writeRegister8(HX8347G_COLADDREND2, 0);
+    writeRegister8(HX8347G_COLADDREND1, TFTWIDTH-1);
+    writeRegister8(HX8347G_ROWADDREND2, (TFTHEIGHT-1)>>8);
+    writeRegister8(HX8347G_ROWADDREND1, (TFTHEIGHT-1)&0xFF);
+    writeCommand(0x0022);            // Write Data to GRAM (R22h)
+  }
+}
+void Adafruit_TFTLCD::setWindow(int x1, int y1, int x2, int y2) {
+ 
+  if (driver == 0x7575) {
+    writeRegister8(HX8347G_COLADDRSTART2, x1>>8);
+    writeRegister8(HX8347G_COLADDRSTART1, x1);
+    writeRegister8(HX8347G_ROWADDRSTART2, y1>>8);
+    writeRegister8(HX8347G_ROWADDRSTART1, y1);
+
+    writeRegister8(HX8347G_COLADDREND2, x2>>8);
+    writeRegister8(HX8347G_COLADDREND1, x2);
+    writeRegister8(HX8347G_ROWADDREND2, y2>>8);
+    writeRegister8(HX8347G_ROWADDREND1, y2);
+
+    writeCommand(0x0022);            // Write Data to GRAM (R22h)
+  }
+}
+
+
+uint16_t Adafruit_TFTLCD::Color565(uint8_t r, uint8_t g, uint8_t b) {
+  uint16_t c;
+  c = r >> 3;
+  c <<= 6;
+  c |= g >> 2;
+  c <<= 5;
+  c |= b >> 3;
+
+  return c;
+}
+
+// fill a rectangle
+void Adafruit_TFTLCD::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 
+		      uint16_t fillcolor) {
+  // smarter version
+  while (h--)
+    drawFastHLine(x, y++, w, fillcolor);
+}
+
+
+void Adafruit_TFTLCD::drawFastVLine(int16_t x, int16_t y, int16_t length, uint16_t color)
+{
+  if (x >= _width) return;
+
+  drawFastLine(x,y,length,color,1);
+}
+
+void Adafruit_TFTLCD::drawFastHLine(int16_t x, int16_t y, int16_t length, uint16_t color)
+{
+  if (y >= _height) return;
+  drawFastLine(x,y,length,color,0);
+}
+
+void Adafruit_TFTLCD::drawFastLine(int16_t x, int16_t y, int16_t length, 
+			  uint16_t color, uint8_t rotflag)
+{
+  if ((driver == 0x9325) || (driver == 0x9328)) {
+
+    uint16_t newentrymod;
+    
+    switch (rotation) {
+    case 0:
+      if (rotflag)
+	newentrymod = 0x1028;   // we want a 'vertical line'
+      else 
+	newentrymod = 0x1030;   // we want a 'horizontal line'
+      break;
+    case 1:
+      swap(x, y);
+      // first up fix the X
+      x = TFTWIDTH - x - 1;
+      if (rotflag)
+	newentrymod = 0x1000;   // we want a 'vertical line'
+      else 
+	newentrymod = 0x1028;   // we want a 'horizontal line'
+      break;
+    case 2:
+      x = TFTWIDTH - x - 1;
+      y = TFTHEIGHT - y - 1;
+      if (rotflag)
+	newentrymod = 0x1008;   // we want a 'vertical line'
+      else 
+	newentrymod = 0x1020;   // we want a 'horizontal line'
+      break;
+    case 3:
+      swap(x,y);
+      y = TFTHEIGHT - y - 1;
+      if (rotflag)
+	newentrymod = 0x1030;   // we want a 'vertical line'
+      else 
+	newentrymod = 0x1008;   // we want a 'horizontal line'
+      break;
+    }
+    
+    writeRegister16(ILI932X_ENTRY_MOD, newentrymod);
+    
+    writeRegister16(ILI932X_GRAM_HOR_AD, x); // GRAM Address Set (Horizontal Address) (R20h)
+    writeRegister16(ILI932X_GRAM_VER_AD, y); // GRAM Address Set (Vertical Address) (R21h)
+    writeCommand(ILI932X_RW_GRAM);  // Write Data to GRAM (R22h)
+  }
+  if (driver == 0x7575) {
+    uint16_t endx, endy;
+    if (rotation == 0) {
+      endx = x, endy = y;
+
+      if (rotflag) endy += length;
+      else	endx += length;
+    } else if (rotation == 1) {
+      swap(x, y);
+      // first up fix the X
+      x = TFTWIDTH - x - 1;
+      endx = x, endy = y;
+
+      if (rotflag) x -= (length-1);
+      else	endy += length;
+    } else if (rotation == 2) {
+      x = TFTWIDTH - x - 1;
+      y = TFTHEIGHT - y - 1;
+      endx = x, endy = y;
+
+      if (rotflag) y -= (length-1);
+      else         x -= (length-1);
+    } else if (rotation == 3) {
+      swap(x,y);
+      y = TFTHEIGHT - y - 1;
+      endx = x, endy = y;
+
+      if (rotflag) endx += (length-1);
+      else         y -= (length-1);
+    }
+    // Serial.print("("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(") -> ");
+
+    writeRegister8(HX8347G_COLADDRSTART2, x>>8);
+    writeRegister8(HX8347G_COLADDRSTART1, x);
+    writeRegister8(HX8347G_ROWADDRSTART2, y>>8);
+    writeRegister8(HX8347G_ROWADDRSTART1, y);
+
+    // Serial.print("("); Serial.print(endx); Serial.print(", "); Serial.print(endy); Serial.println(")");
+    writeRegister8(HX8347G_COLADDREND2, endx>>8);
+    writeRegister8(HX8347G_COLADDREND1, endx);
+    writeRegister8(HX8347G_ROWADDREND2, endy>>8);
+    writeRegister8(HX8347G_ROWADDREND1, endy);
+    writeCommand(0x0022);            // Write Data to GRAM (R22h)
+
+
+  }
+
+  *portOutputRegister(csport) &= ~cspin;  //digitalWrite(_cs, LOW);
+  *portOutputRegister(cdport) |= cdpin;   //digitalWrite(_cd, HIGH);
+  *portOutputRegister(rdport) |= rdpin;   //digitalWrite(_rd, HIGH);
+  *portOutputRegister(wrport) |= wrpin;   //digitalWrite(_wr, HIGH);
+
+  setWriteDir();
+  while (length--) {
+    writeData_unsafe(color); 
+  }
+
+  // set back to default
+  *portOutputRegister(csport) |= cspin;    //digitalWrite(_cs, HIGH);
+
+  if (driver == 0x7575) {
+    goTo(0,0);
+  } else {
+    writeRegister16(ILI932X_ENTRY_MOD, 0x1030);
+  }
+}
+
+
+
+void Adafruit_TFTLCD::fillScreen(uint16_t color) {
+  goTo(0,0);
+
+  uint32_t i;
+  
+  i = 320;
+  i *= 240;
+  
+  *portOutputRegister(csport) &= ~cspin;    //digitalWrite(_cs, LOW);
+  *portOutputRegister(cdport) |= cdpin;     //digitalWrite(_cd, HIGH);
+  *portOutputRegister(rdport) |= rdpin;     //digitalWrite(_rd, HIGH);
+  *portOutputRegister(wrport) |= wrpin;     //digitalWrite(_wr, HIGH);
+
+  setWriteDir();
+  while (i--) {
+    writeData_unsafe(color); 
+  }
+
+  *portOutputRegister(csport) |= cspin;    //digitalWrite(_cs, HIGH);
+}
+
+void Adafruit_TFTLCD::drawPixel(int16_t x, int16_t y, uint16_t color)
+{
+  if ((x >= _width) || (y >= _height)) return;
+
+  // check rotation, move pixel around if necessary
+  switch (rotation) {
+  case 1:
+    swap(x, y);
+    x = TFTWIDTH - x - 1;
+    break;
+  case 2:
+    x = TFTWIDTH - x - 1;
+    y = TFTHEIGHT - y - 1;
+    break;
+  case 3:
+    swap(x, y);
+    y = TFTHEIGHT - y - 1;
+    break;
+  }
+    
+  if (driver == 0x9328 || driver == 0x9325) {
+    writeRegister16(ILI932X_GRAM_HOR_AD, x); // GRAM Address Set (Horizontal Address)
+    writeRegister16(ILI932X_GRAM_VER_AD, y); // GRAM Address Set (Vertical Address)
+    writeCommand(ILI932X_RW_GRAM);  // Write Data to GRAM
+  } else if (driver == 0x7575) {
+    writeRegister8(HX8347G_COLADDRSTART2, x >> 8);
+    writeRegister8(HX8347G_COLADDRSTART1, x & 0xFF);
+    writeRegister8(HX8347G_ROWADDRSTART2, y >> 8);
+    writeRegister8(HX8347G_ROWADDRSTART1, y & 0xFF);
+    writeCommand8(0x0022);            // Write Data to GRAM (R22h)
+  }
+  writeData(color);
+}
+
+uint16_t Adafruit_TFTLCD::readPixel(int16_t x, int16_t y)
+{
+  if ((x >= _width) || (y >= _height)) return 0;
+
+  // check rotation, move pixel around if necessary
+  switch (rotation) {
+  case 1:
+    swap(x, y);
+    x = TFTWIDTH - x - 1;
+    break;
+  case 2:
+    x = TFTWIDTH - x - 1;
+    y = TFTHEIGHT - y - 1;
+    break;
+  case 3:
+    swap(x, y);
+    y = TFTHEIGHT - y - 1;
+    break;
+  }
+    
+  if (driver == 0x9328 || driver == 0x9325) {
+    writeRegister16(ILI932X_GRAM_HOR_AD, x); // GRAM Address Set (Horizontal Address)
+    writeRegister16(ILI932X_GRAM_VER_AD, y); // GRAM Address Set (Vertical Address)
+    writeCommand(ILI932X_RW_GRAM);  // Read Data to GRAM
+  } else if (driver == 0x7575) {
+    writeRegister8(HX8347G_COLADDRSTART2, x >> 8);
+    writeRegister8(HX8347G_COLADDRSTART1, x & 0xFF);
+    writeRegister8(HX8347G_ROWADDRSTART2, y >> 8);
+    writeRegister8(HX8347G_ROWADDRSTART1, y & 0xFF);
+    writeCommand8(0x0022);            // Read Data from GRAM (R22h)
+  }
+  return readData();
+}
+
+
+static const uint16_t HX8347G_regValues[] PROGMEM = {
+  0x2E, 0x89,
+  0x29, 0x8F,
+  0x2B, 0x02,
+  0xE2, 0x00,
+  0xE4, 0x01,
+  0xE5, 0x10,
+  0xE6, 0x01,
+  0xE7, 0x10,
+  0xE8, 0x70,
+  0xF2, 0x00,
+  0xEA, 0x00,
+  0xEB, 0x20,
+  0xEC, 0x3C,
+  0xED, 0xC8,
+  0xE9, 0x38,
+  0xF1, 0x01,
+
+  // skip gamma, do later
+
+  0x1B, 0x1A,
+  0x1A, 0x02,
+  0x24, 0x61,
+  0x25, 0x5C,
+  
+  0x18, 0x36,
+  0x19, 0x01,
+  0x1F, 0x88,
+  TFTLCD_DELAYCMD, 5, // delay 5 ms
+  0x1F, 0x80,
+  TFTLCD_DELAYCMD, 5,
+  0x1F, 0x90,
+  TFTLCD_DELAYCMD, 5,
+  0x1F, 0xD4,
+  TFTLCD_DELAYCMD, 5,
+  0x17, 0x05,
+
+  0x36, 0x09,
+  0x28, 0x38,
+  TFTLCD_DELAYCMD, 40,
+  0x28, 0x3C,
+
+  0x02, 0x00,
+  0x03, 0x00,
+  0x04, 0x00,
+  0x05, 0xEF,
+  0x06, 0x00,
+  0x07, 0x00,
+  0x08, 0x01,
+  0x09, 0x3F,
+};
+
+static const uint16_t ILI932x_regValues[] PROGMEM = {
+  ILI932X_START_OSC, 0x0001,     // start oscillator
+
+  TFTLCD_DELAYCMD, 50,          // this will make a delay of 50 milliseconds
+
+  ILI932X_DRIV_OUT_CTRL, 0x0100, 
+  ILI932X_DRIV_WAV_CTRL, 0x0700,
+  ILI932X_ENTRY_MOD, 0x1030,
+  ILI932X_RESIZE_CTRL, 0x0000,
+  ILI932X_DISP_CTRL2, 0x0202,
+  ILI932X_DISP_CTRL3, 0x0000,
+  ILI932X_DISP_CTRL4, 0x0000,
+  ILI932X_RGB_DISP_IF_CTRL1, 0x0,
+  ILI932X_FRM_MARKER_POS, 0x0,
+  ILI932X_RGB_DISP_IF_CTRL2, 0x0,
+  
+  ILI932X_POW_CTRL1, 0x0000,
+  ILI932X_POW_CTRL2, 0x0007,
+  ILI932X_POW_CTRL3, 0x0000,
+  ILI932X_POW_CTRL4, 0x0000,
+
+  TFTLCD_DELAYCMD, 200,  
+  
+  ILI932X_POW_CTRL1, 0x1690,
+  ILI932X_POW_CTRL2, 0x0227,
+
+  TFTLCD_DELAYCMD, 50,  
+
+  ILI932X_POW_CTRL3, 0x001A,
+
+  TFTLCD_DELAYCMD, 50,  
+
+  ILI932X_POW_CTRL4, 0x1800,
+  ILI932X_POW_CTRL7, 0x002A,
+
+  TFTLCD_DELAYCMD,50,
+  
+  ILI932X_GAMMA_CTRL1, 0x0000,    
+  ILI932X_GAMMA_CTRL2, 0x0000, 
+  ILI932X_GAMMA_CTRL3, 0x0000,
+  ILI932X_GAMMA_CTRL4, 0x0206,   
+  ILI932X_GAMMA_CTRL5, 0x0808,  
+  ILI932X_GAMMA_CTRL6, 0x0007,  
+  ILI932X_GAMMA_CTRL7, 0x0201,
+  ILI932X_GAMMA_CTRL8, 0x0000,  
+  ILI932X_GAMMA_CTRL9, 0x0000,  
+  ILI932X_GAMMA_CTRL10, 0x0000,  
+ 
+  ILI932X_GRAM_HOR_AD, 0x0000,  
+  ILI932X_GRAM_VER_AD, 0x0000,  
+  ILI932X_HOR_START_AD, 0x0000,
+  ILI932X_HOR_END_AD, 0x00EF,
+  ILI932X_VER_START_AD, 0X0000,
+  ILI932X_VER_END_AD, 0x013F,
+   
+
+  ILI932X_GATE_SCAN_CTRL1, 0xA700,     // Driver Output Control (R60h)
+  ILI932X_GATE_SCAN_CTRL2, 0x0003,     // Driver Output Control (R61h)
+  ILI932X_GATE_SCAN_CTRL3, 0x0000,     // Driver Output Control (R62h)
+
+  ILI932X_PANEL_IF_CTRL1, 0X0010,     // Panel Interface Control 1 (R90h)
+  ILI932X_PANEL_IF_CTRL2, 0X0000,
+  ILI932X_PANEL_IF_CTRL3, 0X0003,
+  ILI932X_PANEL_IF_CTRL4, 0X1100,
+  ILI932X_PANEL_IF_CTRL5, 0X0000,
+  ILI932X_PANEL_IF_CTRL6, 0X0000,
+
+  // Display On
+  ILI932X_DISP_CTRL1, 0x0133,     // Display Control (R07h)
+};
+
+void Adafruit_TFTLCD::begin(uint16_t id) {
+  uint16_t a, d;
+
+  constructor(TFTWIDTH, TFTHEIGHT);
+
+  reset();
+  driver = id;
+
+  if (id == 0x9325 || id == 0x9328) {
+    for (uint8_t i = 0; i < sizeof(ILI932x_regValues) / 4; i++) {
+      a = pgm_read_word(ILI932x_regValues + i*2);
+      d = pgm_read_word(ILI932x_regValues + i*2 + 1);
+      
+      if (a == 0xFF) {
+	delay(d);
+      } else {
+	writeRegister16(a, d);
+	//Serial.print("addr: "); Serial.print(a); 
+	//Serial.print(" data: "); Serial.println(d, HEX);
+      }
+    }
+  } else if (id == 0x7575) {
+    for (uint8_t i = 0; i < sizeof(HX8347G_regValues) / 4; i++) {
+      a = pgm_read_word(HX8347G_regValues + i*2);
+      d = pgm_read_word(HX8347G_regValues + i*2 + 1);
+      
+      if (a == 0xFF) {
+	delay(d);
+      } else {
+	writeRegister8(a, d);
+	//Serial.print("addr: "); Serial.print(a); 
+	//Serial.print(" data: "); Serial.println(d, HEX);
+      }
+    }
+  }
+
+}
+/********************************* low level pin initialization */
+
+Adafruit_TFTLCD::Adafruit_TFTLCD(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t reset) {
+  _cs = cs;
+  _cd = cd;
+  _wr = wr;
+  _rd = rd;
+  _reset = reset;
+  
+  rotation = 0;
+  _width = TFTWIDTH;
+  _height = TFTHEIGHT;
+
+  // disable the LCD
+  digitalWrite(_cs, HIGH);
+  pinMode(_cs, OUTPUT);  
+  
+  digitalWrite(_cd, HIGH);
+  pinMode(_cd, OUTPUT);  
+  
+  digitalWrite(_wr, HIGH);
+  pinMode(_wr, OUTPUT);  
+  
+  digitalWrite(_rd, HIGH);
+  pinMode(_rd, OUTPUT);  
+
+  digitalWrite(_reset, HIGH); 
+  pinMode(_reset, OUTPUT); 
+
+  csport = digitalPinToPort(_cs);
+  cdport = digitalPinToPort(_cd);
+  wrport = digitalPinToPort(_wr);
+  rdport = digitalPinToPort(_rd);
+
+  cspin = digitalPinToBitMask(_cs);
+  cdpin = digitalPinToBitMask(_cd);
+  wrpin = digitalPinToBitMask(_wr);
+  rdpin = digitalPinToBitMask(_rd);
+
+  wrportreg = portOutputRegister(wrport);
+
+  cursor_y = cursor_x = 0;
+  textsize = 1;
+  textcolor = 0xFFFF;
+}
+
+
+/********************************** low level pin interface */
+
+void Adafruit_TFTLCD::reset(void) {
+  if (_reset)
+    digitalWrite(_reset, LOW);
+  delay(2); 
+  if (_reset)
+    digitalWrite(_reset, HIGH);
+
+  // resync
+  writeData(0);
+  writeData(0);
+  writeData(0);  
+  writeData(0);
+}
+
+inline void Adafruit_TFTLCD::setWriteDir(void) {
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__)
+  DATADDR2 |= DATA2_MASK;
+  DATADDR1 |= DATA1_MASK;
+#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) 
+
+  #ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  DDRH |= 0x78;
+  DDRB |= 0xB0;
+  DDRG |= _BV(5);
+  #else
+  MEGA_DATADDR = 0xFF;
+  #endif
+#else
+  #error "No pins defined!"
+#endif
+}
+
+inline void Adafruit_TFTLCD::setReadDir(void) {
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328) || (__AVR_ATmega8__)
+  DATADDR2 &= ~DATA2_MASK;
+  DATADDR1 &= ~DATA1_MASK;
+#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) 
+
+  #ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  DDRH &= ~0x78;
+  DDRB &= ~0xB0;
+  DDRG &= ~_BV(5);
+  #else
+  MEGA_DATADDR = 0;
+  #endif
+#else
+  #error "No pins defined!"
+#endif
+}
+
+inline void Adafruit_TFTLCD::write8(uint8_t d) {
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328) || (__AVR_ATmega8__)
+
+  DATAPORT2 = (DATAPORT2 & DATA1_MASK) | 
+    (d & DATA2_MASK);
+  DATAPORT1 = (DATAPORT1 & DATA2_MASK) | 
+    (d & DATA1_MASK); // top 6 bits
+  
+#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) 
+
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+
+  // bit 6/7 (PH3 & 4)
+  // first two bits 0 & 1 (PH5 & 6)
+  PORTH &= ~(0x78);
+  PORTH |= ((d&0xC0) >> 3) | ((d&0x3) << 5);
+
+  // bits 2 & 3 (PB4 & PB5)
+  // bit 5 (PB7)
+  PORTB &= ~(0xB0); 
+  PORTB |= ((d & 0x2C) << 2);
+
+  // bit 4  (PG5)
+  if (d & _BV(4))
+    PORTG |= _BV(5);
+  else
+    PORTG &= ~_BV(5);
+
+  #else
+     MEGA_DATAPORT = d;  
+  #endif
+
+#else
+  #error "No pins defined!"
+#endif
+}
+
+inline uint8_t Adafruit_TFTLCD::read8(void) {
+ uint8_t d;
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328) || (__AVR_ATmega8__)
+
+ d = DATAPIN1 & DATA1_MASK; 
+ d |= DATAPIN2 & DATA2_MASK; 
+
+#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__)  || defined(__AVR_ATmega1280__) 
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+
+  // bit 6/7 (PH3 & 4)
+  // first two bits 0 & 1 (PH5 & 6)
+ d = (PINH & 0x60) >> 5;
+ d |= (PINH & 0x18) << 3;
+
+  // bits 2 & 3 & 5 (PB4 & PB5, PB7)
+ d |= (PINB & 0xB0) >> 2;
+
+  // bit 4  (PG5)
+  if (PING & _BV(5))
+    d |= _BV(4);
+
+  #else
+    d = MEGA_DATAPIN;  
+  #endif
+#else
+  #error "No pins defined!"
+#endif
+
+ return d;
+}
+
+/********************************** low level readwrite interface */
+
+// the C/D pin is high during write
+void Adafruit_TFTLCD::writeData(uint16_t data) {
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT |= _BV(WRPIN);
+  CSPORT &= ~_BV(CSPIN);
+  CDPORT |= _BV(CDPIN);
+  RDPORT |= _BV(RDPIN);
+#else
+  *wrportreg |=  wrpin;                   //digitalWrite(_wr, HIGH);
+  *portOutputRegister(csport) &= ~cspin;  //digitalWrite(_cs, LOW);
+  *portOutputRegister(cdport) |= cdpin;   //digitalWrite(_cd, HIGH);
+  *portOutputRegister(rdport) |= rdpin;   //digitalWrite(_rd, HIGH);
+#endif
+
+  setWriteDir();
+  write8(data >> 8);
+  
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+#else
+  *wrportreg &= ~wrpin;    //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;    //digitalWrite(_wr, HIGH);
+#endif
+
+  write8(data);
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+  CSPORT |= _BV(CSPIN);
+#else
+  *wrportreg &= ~wrpin;   //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;   //digitalWrite(_wr, HIGH);
+  *portOutputRegister(csport) |= cspin;    //digitalWrite(_cs, HIGH);
+#endif
+}
+
+inline void Adafruit_TFTLCD::writeRegister8(uint8_t addr, uint8_t data) {
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT |= _BV(WRPIN);
+  CSPORT &= ~_BV(CSPIN);
+  CDPORT &= ~_BV(CDPIN);
+  RDPORT |= _BV(RDPIN);
+#else
+  *wrportreg |=  wrpin;                    //digitalWrite(_wr, HIGH);
+  *portOutputRegister(csport) &= ~cspin;   //digitalWrite(_cs, LOW);
+  *portOutputRegister(cdport) &= ~cdpin;   //digitalWrite(_cd, HIGH);
+  *portOutputRegister(rdport) |= rdpin;    //digitalWrite(_rd, HIGH);
+#endif
+
+  setWriteDir();
+  write8(addr);
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+#else
+  *wrportreg &= ~wrpin;   //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;   //digitalWrite(_wr, HIGH);
+#endif
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  CDPORT |= _BV(CDPIN);
+#else
+  *portOutputRegister(cdport) |= cdpin;     //digitalWrite(_cd, HIGH);
+#endif
+
+  write8(data);
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+  CSPORT |= _BV(CSPIN);
+#else
+  *wrportreg &= ~wrpin;                    //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;                    //digitalWrite(_wr, HIGH);
+  *portOutputRegister(csport) |= cspin;    //digitalWrite(_cs, HIGH);
+#endif
+}
+
+// this is a 'sped up' version, with no direction setting, or pin initialization
+// not for external usage, but it does speed up stuff like a screen fill
+inline void Adafruit_TFTLCD::writeData_unsafe(uint16_t data) {
+  write8(data >> 8);
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+#else
+  *wrportreg &= ~wrpin;   //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;   //digitalWrite(_wr, HIGH);
+#endif
+
+  write8(data);
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+#else
+  *wrportreg &= ~wrpin;   //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;   //digitalWrite(_wr, HIGH);
+#endif
+}
+
+// the C/D pin is low during write
+void Adafruit_TFTLCD::writeCommand(uint16_t cmd) {
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT |= _BV(WRPIN);
+  CSPORT &= ~_BV(CSPIN);
+  CDPORT &= ~_BV(CDPIN);
+  RDPORT |= _BV(RDPIN);
+#else
+  *wrportreg |=  wrpin;                    //digitalWrite(_wr, HIGH);
+  *portOutputRegister(csport) &= ~cspin;   //digitalWrite(_cs, LOW);
+  *portOutputRegister(cdport) &= ~cdpin;   //digitalWrite(_cd, HIGH);
+  *portOutputRegister(rdport) |= rdpin;    //digitalWrite(_rd, HIGH);
+#endif
+
+  setWriteDir();
+  write8(cmd >> 8);
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+#else
+  *wrportreg &= ~wrpin;    //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;    //digitalWrite(_wr, HIGH);
+#endif
+
+  write8(cmd);
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+  CSPORT |= _BV(CSPIN);
+#else
+  *wrportreg &= ~wrpin;    //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;    //digitalWrite(_wr, HIGH);
+  *portOutputRegister(csport) |= cspin;   //digitalWrite(_cs, HIGH);
+#endif
+}
+
+inline void Adafruit_TFTLCD::writeCommand8(uint8_t cmd) {
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT |= _BV(WRPIN);
+  CSPORT &= ~_BV(CSPIN);
+  CDPORT &= ~_BV(CDPIN);
+  RDPORT |= _BV(RDPIN);
+#else
+  *wrportreg |=  wrpin;                    //digitalWrite(_wr, HIGH);
+  *portOutputRegister(csport) &= ~cspin;   //digitalWrite(_cs, LOW);
+  *portOutputRegister(cdport) &= ~cdpin;   //digitalWrite(_cd, HIGH);
+  *portOutputRegister(rdport) |= rdpin;    //digitalWrite(_rd, HIGH);
+#endif
+
+  setWriteDir();
+  write8(cmd);
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  WRPORT &= ~_BV(WRPIN);
+  WRPORT |= _BV(WRPIN);
+  CSPORT |= _BV(CSPIN);
+#else
+  *wrportreg &= ~wrpin;   //digitalWrite(_wr, LOW);
+  *wrportreg |=  wrpin;   //digitalWrite(_wr, HIGH);
+  *portOutputRegister(csport) |= cspin;  //digitalWrite(_cs, HIGH);
+#endif
+}
+
+uint16_t Adafruit_TFTLCD::readData() {
+ uint16_t d = 0;
+ 
+  *portOutputRegister(csport) &= ~cspin;  //digitalWrite(_cs, LOW);
+  *portOutputRegister(cdport) |= cdpin;   //digitalWrite(_cd, HIGH);
+  *portOutputRegister(rdport) |= rdpin;   //digitalWrite(_rd, HIGH);
+  *portOutputRegister(wrport) |= wrpin;   //digitalWrite(_wr, HIGH);
+  
+  setReadDir();
+
+  *portOutputRegister(rdport) &= ~rdpin;  //digitalWrite(_rd, LOW);
+
+  delayMicroseconds(10);
+  d = read8();
+  d <<= 8;
+
+  *portOutputRegister(rdport) |= rdpin;   //digitalWrite(_rd, HIGH);
+  *portOutputRegister(rdport) &= ~rdpin;  //digitalWrite(_rd, LOW);
+
+  delayMicroseconds(10);
+  d |= read8();
+
+  *portOutputRegister(rdport) |= rdpin;   //digitalWrite(_rd, HIGH);
+  *portOutputRegister(csport) |= cspin;   //digitalWrite(_cs, HIGH);
+   
+  return d;
+}
+
+
+/************************************* medium level data reading/writing */
+
+uint16_t Adafruit_TFTLCD::readRegister(uint16_t addr) {
+   writeCommand(addr);
+   return readData();
+}
+
+
+void Adafruit_TFTLCD::writeRegister16(uint16_t addr, uint16_t data) {
+  writeCommand(addr);
+  writeData(data);
+}
+
+
+
+

Adafruit_TFTLCD-Library/Adafruit_TFTLCD.h

+// Graphics library by ladyada/adafruit with init code from Rossum 
+// MIT license
+
+#ifndef _ADAFRUIT_TFTLCD_H_
+#define _ADAFRUIT_TFTLCD_H_
+
+#if ARDUINO >= 100
+ #include "Arduino.h"
+#else
+ #include "WProgram.h"
+#endif
+#include <Adafruit_GFX.h>
+
+// comment or uncomment the next line for special pinout!
+#define USE_ADAFRUIT_SHIELD_PINOUT
+
+
+// register names from Peter Barrett's Microtouch code
+
+#define ILI932X_START_OSC			0x00
+#define ILI932X_DRIV_OUT_CTRL		0x01
+#define ILI932X_DRIV_WAV_CTRL		0x02
+#define ILI932X_ENTRY_MOD			0x03
+#define ILI932X_RESIZE_CTRL			0x04
+#define ILI932X_DISP_CTRL1			0x07
+#define ILI932X_DISP_CTRL2			0x08
+#define ILI932X_DISP_CTRL3			0x09
+#define ILI932X_DISP_CTRL4			0x0A
+#define ILI932X_RGB_DISP_IF_CTRL1	0x0C
+#define ILI932X_FRM_MARKER_POS		0x0D
+#define ILI932X_RGB_DISP_IF_CTRL2	0x0F
+#define ILI932X_POW_CTRL1			0x10
+#define ILI932X_POW_CTRL2			0x11
+#define ILI932X_POW_CTRL3			0x12
+#define ILI932X_POW_CTRL4			0x13
+#define ILI932X_GRAM_HOR_AD			0x20
+#define ILI932X_GRAM_VER_AD			0x21
+#define ILI932X_RW_GRAM				0x22
+#define ILI932X_POW_CTRL7			0x29
+#define ILI932X_FRM_RATE_COL_CTRL	0x2B
+#define ILI932X_GAMMA_CTRL1			0x30
+#define ILI932X_GAMMA_CTRL2			0x31
+#define ILI932X_GAMMA_CTRL3			0x32
+#define ILI932X_GAMMA_CTRL4			0x35 
+#define ILI932X_GAMMA_CTRL5			0x36
+#define ILI932X_GAMMA_CTRL6			0x37
+#define ILI932X_GAMMA_CTRL7			0x38
+#define ILI932X_GAMMA_CTRL8			0x39
+#define ILI932X_GAMMA_CTRL9			0x3C
+#define ILI932X_GAMMA_CTRL10			0x3D
+#define ILI932X_HOR_START_AD			0x50
+#define ILI932X_HOR_END_AD			0x51
+#define ILI932X_VER_START_AD			0x52
+#define ILI932X_VER_END_AD			0x53
+#define ILI932X_GATE_SCAN_CTRL1		0x60
+#define ILI932X_GATE_SCAN_CTRL2		0x61
+#define ILI932X_GATE_SCAN_CTRL3		0x6A
+#define ILI932X_PART_IMG1_DISP_POS	0x80
+#define ILI932X_PART_IMG1_START_AD	0x81
+#define ILI932X_PART_IMG1_END_AD		0x82
+#define ILI932X_PART_IMG2_DISP_POS	0x83
+#define ILI932X_PART_IMG2_START_AD	0x84
+#define ILI932X_PART_IMG2_END_AD		0x85
+#define ILI932X_PANEL_IF_CTRL1		0x90
+#define ILI932X_PANEL_IF_CTRL2		0x92
+#define ILI932X_PANEL_IF_CTRL3		0x93
+#define ILI932X_PANEL_IF_CTRL4		0x95
+#define ILI932X_PANEL_IF_CTRL5		0x97
+#define ILI932X_PANEL_IF_CTRL6		0x98
+
+#define HX8347G_COLADDRSTART2 0x02
+#define HX8347G_COLADDRSTART1 0x03
+#define HX8347G_COLADDREND2 0x04
+#define HX8347G_COLADDREND1 0x05
+
+#define HX8347G_ROWADDRSTART2 0x06
+#define HX8347G_ROWADDRSTART1 0x07
+#define HX8347G_ROWADDREND2 0x08
+#define HX8347G_ROWADDREND1 0x09
+
+#define HX8347G_MEMACCESS 0x16
+
+
+#define TFTLCD_DELAYCMD                 0xFF
+
+#define swap(a, b) { int16_t t = a; a = b; b = t; }
+
+class Adafruit_TFTLCD : public Adafruit_GFX {
+ public:
+  Adafruit_TFTLCD(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t reset);
+
+  uint16_t Color565(uint8_t r, uint8_t g, uint8_t b);
+
+  // drawing primitives!
+  void drawPixel(int16_t x, int16_t y, uint16_t color);
+  uint16_t readPixel(int16_t x, int16_t y);
+  void fillScreen(uint16_t color);
+  void drawFastVLine(int16_t x0, int16_t y0, int16_t length, uint16_t color);
+  void drawFastHLine(int16_t x0, int16_t y0, int16_t length, uint16_t color);
+
+  void fillRect(int16_t x0, int16_t y0, int16_t w, int16_t h, uint16_t color);
+
+  // commands
+  void begin(uint16_t id = 0x9325);
+  void goTo(int x, int y);
+  void setWindow(int x1, int y1, int x2, int y2);
+  void reset(void);
+
+  /* low level */
+
+  void writeData(uint16_t d);
+  void writeCommand(uint16_t c);
+  void writeCommand8(uint8_t c);
+  uint16_t readData(void);
+  uint16_t readRegister(uint16_t addr);
+  void writeRegister8(uint8_t a, uint8_t d);
+  void writeRegister16(uint16_t addr, uint16_t data);
+
+  static const uint16_t TFTWIDTH = 240;
+  static const uint16_t TFTHEIGHT = 320;
+
+  void writeData_unsafe(uint16_t d);
+
+  void setWriteDir(void);
+  void setReadDir(void);
+  void write8(uint8_t d);
+
+ private:
+  uint16_t driver;
+
+  void drawFastLine(int16_t x0, int16_t y0, int16_t l, uint16_t color, uint8_t flag);
+  uint8_t read8(void);
+
+  uint8_t _cs, _cd, _reset, _wr, _rd;
+
+  uint8_t csport, cdport, wrport, rdport;
+  uint8_t cspin, cdpin, wrpin, rdpin;
+};
+
+#endif

Adafruit_TFTLCD-Library/README.txt

+This is a library for the Adafruit 2.8" TFT display.
+This library works with the Adafruit 2.8" TFT Breakout w/SD card
+  ----> http://www.adafruit.com/products/335
+as well as Adafruit TFT Touch Shield
+  ----> http://www.adafruit.com/products/376
+ 
+Check out the links above for our tutorials and wiring diagrams.
+These displays use 8-bit parallel to communicate, 12 or 13 pins are required
+to interface (RST is optional).
+Adafruit invests time and resources providing this open source code,
+please support Adafruit and open-source hardware by purchasing
+products from Adafruit!
+
+Written by Limor Fried/Ladyada for Adafruit Industries.
+MIT license, all text above must be included in any redistribution
+
+To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_TFTLCD. Check that the Adafruit_TFTLCD folder contains Adafruit_TFTLCD.cpp and Adafruit_TFTLCD.
+
+Place the Adafruit_TFT library folder your <arduinosketchfolder>/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE
+
+Also requires the Adafruit_GFX library for Arduino. https://github.com/adafruit/Adafruit-GFX-Library
Add a comment to this file

Adafruit_TFTLCD-Library/bitmaps/miniwoof.bmp

Added
New image
Add a comment to this file

Adafruit_TFTLCD-Library/bitmaps/test.bmp

Added
New image
Add a comment to this file

Adafruit_TFTLCD-Library/bitmaps/woof.bmp

Added
New image

Adafruit_TFTLCD-Library/examples/graphicstest/graphicstest.pde

+#include <Adafruit_GFX.h>    // Core graphics library
+#include <Adafruit_TFTLCD.h> // Hardware-specific library
+
+// The control pins can connect to any pins but we'll use the 
+// analog lines since that means we can double up the pins
+// with the touch screen (see the TFT paint example)
+#define LCD_CS A3    // Chip Select goes to Analog 3
+#define LCD_CD A2    // Command/Data goes to Analog 2
+#define LCD_WR A1    // LCD Write goes to Analog 1
+#define LCD_RD A0    // LCD Read goes to Analog 0
+
+// you can also just connect RESET to the arduino RESET pin
+#define LCD_RESET A4
+
+/* For the 8 data pins:
+Duemilanove/Diecimila/UNO/etc ('168 and '328 chips) microcontoller:
+D0 connects to digital 8
+D1 connects to digital 9
+D2 connects to digital 2
+D3 connects to digital 3
+D4 connects to digital 4
+D5 connects to digital 5
+D6 connects to digital 6
+D7 connects to digital 7
+
+For Mega's use pins 22 thru 29 (on the double header at the end)
+*/
+
+// Color definitions
+#define	BLACK           0x0000
+#define	BLUE            0x001F
+#define	RED             0xF800
+#define	GREEN           0x07E0
+#define CYAN            0x07FF
+#define MAGENTA         0xF81F
+#define YELLOW          0xFFE0 
+#define WHITE           0xFFFF
+
+
+Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
+
+void setup(void) {
+  Serial.begin(9600);
+  Serial.println("8 Bit LCD test!");
+
+#ifdef USE_ADAFRUIT_SHIELD_PINOUT
+  Serial.println("Using Adafruit 2.8 inch TFT Arduino Shield Pinout");
+#else
+  Serial.println("Using Adafruit 2.8 inch TFT Breakout Pinout");
+#endif
+
+  tft.reset();
+  
+  uint16_t identifier = tft.readRegister(0x0);
+  if (identifier == 0x9325) {
+    Serial.println("Found ILI9325");
+  } else if (identifier == 0x9328) {
+    Serial.println("Found ILI9328");
+  } else if (identifier == 0x7575) {
+    Serial.println("Found HX8347G");
+  } else {
+    Serial.print("Unknown driver chip ");
+    Serial.println(identifier, HEX);
+    while (1);
+  }  
+ 
+  tft.begin(identifier);
+  
+  uint32_t time = millis();
+  testtext(RED);
+  Serial.println(millis() - time);
+  delay(2000);
+  time = millis();
+  testlines(CYAN);
+  Serial.println(millis() - time);
+  delay(500);
+  time = millis();
+  testfastlines(RED, BLUE);
+  Serial.println(millis() - time);
+  delay(500);
+  testdrawrects(GREEN);
+  delay(500);
+  testfillrects(YELLOW, MAGENTA);
+  delay(500);
+  tft.fillScreen(BLACK);
+  testfillcircles(10, MAGENTA);
+  testdrawcircles(10, WHITE);
+  delay(500); 
+  testtriangles();
+  delay(500); 
+  testfilltriangles();
+  delay(500); 
+  testRoundRect();
+  delay(500); 
+  testFillRoundRect();
+  
+}
+
+void loop(void) {
+  for (uint8_t rotation=0; rotation<4; rotation++) {
+    tft.setRotation(rotation); 
+    testtext(RED);
+    delay(1000);
+  }
+}
+
+
+
+void testFillRoundRect() {
+  tft.fillScreen(BLACK);
+  
+  for (int16_t x=tft.width(); x > 20 ; x-=6) {
+    tft.fillRoundRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, x/8,  tft.Color565(0, x, 0));
+ }
+}
+
+void testRoundRect() {
+  tft.fillScreen(BLACK);
+  
+  for (int16_t x=0; x < tft.width(); x+=6) {
+    tft.drawRoundRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, x/8, tft.Color565(x, 0, 0));
+ }
+}
+
+void testtriangles() {
+  tft.fillScreen(BLACK);
+  for (int16_t i=0; i<tft.width()/2; i+=5) {
+    tft.drawTriangle(tft.width()/2, tft.height()/2-i,
+                     tft.width()/2-i, tft.height()/2+i,
+                     tft.width()/2+i, tft.height()/2+i, tft.Color565(0, 0, i));
+  }
+}
+
+void testfilltriangles() {
+  tft.fillScreen(BLACK);
+  
+  for (int16_t i=tft.width()/2; i>10; i-=5) {
+    tft.fillTriangle(tft.width()/2, tft.height()/2-i,
+                     tft.width()/2-i, tft.height()/2+i,
+                     tft.width()/2+i, tft.height()/2+i, 
+                     tft.Color565(0, i, i));
+    tft.drawTriangle(tft.width()/2, tft.height()/2-i,
+                     tft.width()/2-i, tft.height()/2+i,
+                     tft.width()/2+i, tft.height()/2+i, tft.Color565(i, i, 0));    
+  }
+}
+void testtext(uint16_t color) {
+  tft.fillScreen(BLACK);
+  tft.setCursor(0, 20);
+  tft.setTextColor(color);
+  tft.setTextSize(1);
+  tft.println("Hello World!");
+  tft.setTextSize(2);
+  tft.println(1234.56);
+  tft.setTextSize(3);
+  tft.println(0xDEADBEEF, HEX);
+}
+
+void testfillcircles(uint8_t radius, uint16_t color) {
+  for (int16_t x=radius; x < tft.width(); x+=radius*2) {
+    for (int16_t y=radius; y < tft.height(); y+=radius*2) {
+      tft.fillCircle(x, y, radius, color);
+    }
+  }  
+}
+
+void testdrawcircles(uint8_t radius, uint16_t color) {
+  for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
+    for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
+      tft.drawCircle(x, y, radius, color);
+    }
+  }  
+}
+
+
+void testfillrects(uint16_t color1, uint16_t color2) {
+ tft.fillScreen(BLACK);
+ for (int16_t x=tft.width()-1; x > 6; x-=6) {
+   //Serial.println(x, DEC);
+   tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
+   tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
+ }
+}
+
+void testdrawrects(uint16_t color) {
+ tft.fillScreen(BLACK);
+ for (int16_t x=0; x < tft.width(); x+=6) {
+   tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
+ }
+}
+
+void testfastlines(uint16_t color1, uint16_t color2) {
+   tft.fillScreen(BLACK);
+   for (int16_t y=0; y < tft.height(); y+=5) {
+     tft.drawFastHLine(0, y, tft.width(), color1);
+   }
+   for (int16_t x=0; x < tft.width(); x+=5) {
+     tft.drawFastVLine(x, 0, tft.height(), color2);
+   }
+  
+}
+
+void testlines(uint16_t color) {
+   tft.fillScreen(BLACK);
+   for (int16_t x=0; x < tft.width(); x+=6) {
+     tft.drawLine(0, 0, x, tft.height()-1, color);
+   }
+   for (int16_t y=0; y < tft.height(); y+=6) {
+     tft.drawLine(0, 0, tft.width()-1, y, color);
+   }
+   
+   tft.fillScreen(BLACK);
+   for (int16_t x=0; x < tft.width(); x+=6) {
+     tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
+   }
+   for (int16_t y=0; y < tft.height(); y+=6) {
+     tft.drawLine(tft.width()-1, 0, 0, y, color);
+   }
+   
+   tft.fillScreen(BLACK);
+   for (int16_t x=0; x < tft.width(); x+=6) {
+     tft.drawLine(0, tft.height()-1, x, 0, color);
+   }
+   for (int16_t y=0; y < tft.height(); y+=6) {
+     tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
+   }
+
+   tft.fillScreen(BLACK);
+   for (int16_t x=0; x < tft.width(); x+=6) {
+     tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
+   }
+   for (int16_t y=0; y < tft.height(); y+=6) {
+     tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
+   }
+}
+
+
+void testBars() {
+  int16_t i,j;
+  for(i=0; i < tft.height(); i++)
+  {
+    for(j=0; j < tft.width(); j++)
+    {
+      if(i>279) tft.writeData(WHITE);
+      else if(i>239) tft.writeData(BLUE);
+      else if(i>199) tft.writeData(GREEN);
+      else if(i>159) tft.writeData(CYAN);
+      else if(i>119) tft.writeData(RED);
+      else if(i>79) tft.writeData(MAGENTA);
+      else if(i>39) tft.writeData(YELLOW);
+      else tft.writeData(BLACK);
+    }
+  }
+}

Adafruit_TFTLCD-Library/examples/rotationtest/rotationtest.pde

+#include <Adafruit_GFX.h>    // Core graphics library
+#include <Adafruit_TFTLCD.h> // Hardware-specific library
+
+// The control pins can connect to any pins but we'll use the 
+// analog lines since that means we can double up the pins
+// with the touch screen (see the TFT paint example)
+#define LCD_CS A3    // Chip Select goes to Analog 3
+#define LCD_CD A2    // Command/Data goes to Analog 2
+#define LCD_WR A1    // LCD Write goes to Analog 1
+#define LCD_RD A0    // LCD Read goes to Analog 0
+
+// you can also just connect RESET to the arduino RESET pin
+#define LCD_RESET A4
+
+/* For the 8 data pins:
+Duemilanove/Diecimila/UNO/etc ('168 and '328 chips) microcontoller:
+D0 connects to digital 8
+D1 connects to digital 9
+D2 connects to digital 2
+D3 connects to digital 3
+D4 connects to digital 4
+D5 connects to digital 5
+D6 connects to digital 6
+D7 connects to digital 7
+
+For Mega's use pins 22 thru 29 (on the double header at the end)
+*/
+
+// Color definitions
+#define	BLACK           0x0000
+#define	BLUE            0x001F
+#define	RED             0xF800
+#define	GREEN           0x07E0
+#define CYAN            0x07FF
+#define MAGENTA         0xF81F
+#define YELLOW          0xFFE0 
+#define WHITE           0xFFFF
+
+Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
+
+void setup(void) {
+  Serial.begin(9600);
+  Serial.println("8 Bit LCD test!");
+  
+  tft.reset();
+  
+  uint16_t identifier = tft.readRegister(0x0);
+  if (identifier == 0x9325) {
+    Serial.println("Found ILI9325");
+  } else if (identifier == 0x9328) {
+    Serial.println("Found ILI9328");
+  } else if (identifier == 0x7575) {
+    Serial.println("Found HX8347G");
+  } else {
+    Serial.print("Unknown driver chip ");
+    Serial.println(identifier, HEX);
+    while (1);
+  }  
+ 
+  tft.begin(identifier);
+  
+  tft.fillScreen(BLACK);
+
+  Serial.println("This is a test of the rotation capabilities of the TFT library!");
+  Serial.println("Press <SEND> (or type a character) to advance");
+}
+
+void loop(void) {
+  rotatePixel();
+  rotateLine();
+  rotateFastline();
+  rotateDrawrect();
+  rotateFillrect();
+  rotateDrawcircle();
+  rotateFillcircle();
+  rotateText();
+}
+
+void rotateText() {
+  for (uint8_t i=0; i<4; i++) {
+    tft.fillScreen(BLACK);
+    Serial.println(tft.getRotation(), DEC);
+
+    tft.setCursor(0, 30);
+    tft.setTextColor(RED);  
+    tft.setTextSize(1);
+    tft.println("Hello World!");
+    tft.setTextColor(YELLOW);
+    tft.setTextSize(2);
+    tft.println("Hello World!");
+    tft.setTextColor(GREEN);
+    tft.setTextSize(3);
+    tft.println("Hello World!");
+    tft.setTextColor(BLUE);
+    tft.setTextSize(4);
+    tft.print(1234.567);
+
+    while (!Serial.available());
+    Serial.read();  Serial.read();  Serial.read();
+  
+    tft.setRotation(tft.getRotation()+1);
+  }
+}
+
+void rotateFillcircle(void) {
+  for (uint8_t i=0; i<4; i++) {
+    tft.fillScreen(BLACK);
+    Serial.println(tft.getRotation(), DEC);
+  
+    tft.fillCircle(10, 30, 10, YELLOW);
+ 
+    while (!Serial.available());
+    Serial.read();  Serial.read();  Serial.read();
+  
+    tft.setRotation(tft.getRotation()+1);
+  }
+}
+
+void rotateDrawcircle(void) {
+  for (uint8_t i=0; i<4; i++) {
+    tft.fillScreen(BLACK);
+    Serial.println(tft.getRotation(), DEC);
+
+    tft.drawCircle(10, 30, 10, YELLOW);
+ 
+    while (!Serial.available());
+    Serial.read();  Serial.read();  Serial.read();
+  
+    tft.setRotation(tft.getRotation()+1);
+  }
+}
+
+void rotateFillrect(void) {
+  for (uint8_t i=0; i<4; i++) {
+    tft.fillScreen(BLACK);
+    Serial.println(tft.getRotation(), DEC);
+  
+    tft.fillRect(10, 20, 10, 20, GREEN);
+ 
+    while (!Serial.available());
+    Serial.read();  Serial.read();  Serial.read();
+  
+    tft.setRotation(tft.getRotation()+1);
+  }
+}
+
+
+void rotateDrawrect(void) {
+  for (uint8_t i=0; i<4; i++) {
+    tft.fillScreen(BLACK);
+    Serial.println(tft.getRotation(), DEC);
+
+  
+    tft.drawRect(10, 20, 10, 20, GREEN);
+ 
+    while (!Serial.available());
+    Serial.read();  Serial.read();  Serial.read();
+  
+    tft.setRotation(tft.getRotation()+1);
+  }
+}
+
+
+void rotateFastline(void) {
+  for (uint8_t i=0; i<4; i++) {
+    tft.fillScreen(BLACK);
+    Serial.println(tft.getRotation(), DEC);
+  
+    tft.drawFastHLine(0, 20, tft.width(), RED);
+    tft.drawFastVLine(20, 0, tft.height(), BLUE);
+  
+    while (!Serial.available());
+    Serial.read();  Serial.read();  Serial.read();
+  
+    tft.setRotation(tft.getRotation()+1);
+  }
+}
+
+
+void rotateLine(void) {
+  for (uint8_t i=0; i<4; i++) {
+    tft.fillScreen(BLACK);
+    Serial.println(tft.getRotation(), DEC);
+
+    tft.drawLine(tft.width()/2, tft.height()/2, 0, 0, RED);
+    while (!Serial.available());
+    Serial.read();  Serial.read();  Serial.read();
+  
+    tft.setRotation(tft.getRotation()+1);
+  }
+}
+
+void rotatePixel(void) {
+  for (uint8_t i=0; i<4; i++) {
+    tft.fillScreen(BLACK);
+    Serial.println(tft.getRotation(), DEC);
+
+    tft.drawPixel(10,20, RED);
+    while (!Serial.available());
+    Serial.read();  Serial.read();  Serial.read();
+  
+    tft.setRotation(tft.getRotation()+1);
+  }
+}
Add a comment to this file

Adafruit_TFTLCD-Library/examples/tftbmp/miniwoof.bmp

Added
New image
Add a comment to this file

Adafruit_TFTLCD-Library/examples/tftbmp/test.bmp

Added
New image

Adafruit_TFTLCD-Library/examples/tftbmp/tftbmp.pde

+#include <Adafruit_GFX.h>    // Core graphics library
+#include <Adafruit_TFTLCD.h> // Hardware-specific library
+#include <SD.h>
+
+// The control pins can connect to any pins but we'll use the 
+// analog lines since that means we can double up the pins
+// with the touch screen (see the TFT paint example)
+#define LCD_CS A3    // Chip Select goes to Analog 3
+#define LCD_CD A2    // Command/Data goes to Analog 2
+#define LCD_WR A1    // LCD Write goes to Analog 1
+#define LCD_RD A0    // LCD Read goes to Analog 0
+/* For the 8 data pins:
+Duemilanove/Diecimila/UNO/etc ('168 and '328 chips) microcontoller:
+D0 connects to digital 8
+D1 connects to digital 9
+D2 connects to digital 2
+D3 connects to digital 3
+D4 connects to digital 4
+D5 connects to digital 5
+D6 connects to digital 6
+D7 connects to digital 7
+
+For Mega's use pins 22 thru 29 (on the double header at the end)
+*/
+
+// For Arduino Uno/Duemilanove, etc
+//  connect the SD card with DI going to pin 11, DO going to pin 12 and SCK going to pin 13 (standard)
+//  Then pin 10 goes to CS (or whatever you have set up)
+#define SD_CS 10     // Set the chip select line to whatever you use (10 doesnt conflict with the library)
+
+// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
+// There are examples in the sketch folder
+
+// our TFT wiring
+Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, 0);
+
+// the file itself
+File bmpFile;
+
+// information we extract about the bitmap file
+int bmpWidth, bmpHeight;
+uint8_t bmpDepth, bmpImageoffset;
+
+
+void setup()
+{
+  Serial.begin(9600);
+ 
+  tft.reset();
+  
+  // find the TFT display
+  uint16_t identifier = tft.readRegister(0x0);
+  if (identifier == 0x9325) {
+    Serial.println("Found ILI9325");
+  } else if (identifier == 0x9328) {
+    Serial.println("Found ILI9328");
+  } else if (identifier == 0x7575) {
+    Serial.println("Found HX8347G");
+  } else {
+    Serial.print("Unknown driver chip ");
+    Serial.println(identifier, HEX);
+    while (1);
+  }  
+ 
+  tft.begin(identifier);
+  
+  Serial.print("Initializing SD card...");
+  pinMode(10, OUTPUT);
+
+  if (!SD.begin(10)) {
+    Serial.println("failed!");
+    return;
+  }
+  Serial.println("SD OK!");
+
+  bmpFile = SD.open("woof.bmp");
+
+  if (! bmpFile) {
+    Serial.println("didnt find image");
+    while (1);
+  }
+  
+  if (! bmpReadHeader(bmpFile)) { 
+     Serial.println("bad bmp");
+     return;
+  }
+  
+  Serial.print("image size "); 
+  Serial.print(bmpWidth, DEC);
+  Serial.print(", ");
+  Serial.println(bmpHeight, DEC);
+ 
+  bmpdraw(bmpFile, 0, 0);
+  delay(1000);
+  
+  bmpFile.close();
+  bmpFile = SD.open("miniwoof.bmp");
+
+  if (! bmpFile) {
+    Serial.println("didnt find image");
+    while (1);
+  }
+  
+  if (! bmpReadHeader(bmpFile)) { 
+     Serial.println("bad bmp");
+     return;
+  }
+  
+  Serial.print("image size "); 
+  Serial.print(bmpWidth, DEC);
+  Serial.print(", ");
+  Serial.println(bmpHeight, DEC);
+}
+
+void loop()
+{
+  tft.setRotation(0);
+  tft.fillScreen(0);
+  bmpdraw(bmpFile, 50, 50);
+  delay(1000);
+
+  tft.setRotation(1);
+  tft.fillScreen(0);
+  bmpdraw(bmpFile, 50, 50);
+  delay(1000);
+
+  tft.setRotation(2);
+  tft.fillScreen(0);
+  bmpdraw(bmpFile, 50, 50);
+  delay(1000);
+
+  tft.setRotation(3);
+  tft.fillScreen(0);
+  bmpdraw(bmpFile, 50, 50);
+  delay(1000);
+
+}
+
+
+/*********************************************/
+// This procedure reads a bitmap and draws it to the screen
+// its sped up by reading many pixels worth of data at a time
+// instead of just one pixel at a time. increading the buffer takes
+// more RAM but makes the drawing a little faster. 20 pixels' worth
+// is probably a good place
+
+#define BUFFPIXEL 20
+
+void bmpdraw(File f, int x, int y) {
+  bmpFile.seek(bmpImageoffset);
+  
+  uint32_t time = millis();
+  uint16_t p;
+  uint8_t g, b;
+  int i, j;
+  
+  uint8_t sdbuffer[3 * BUFFPIXEL];  // 3 * pixels to buffer
+  uint8_t buffidx = 3*BUFFPIXEL;
+  
+  Serial.print("rotation = "); Serial.println(tft.getRotation(), DEC);
+  
+  for (i=0; i< bmpHeight; i++) {
+    // bitmaps are stored with the BOTTOM line first so we have to move 'up'
+
+    if (tft.getRotation() == 3) {
+      tft.goTo(x, y+bmpHeight-i); 
+    } else if  (tft.getRotation() == 2) {
+      tft.goTo(x+i, y);
+    } else if  (tft.getRotation() == 1) {
+        tft.goTo(x+bmpWidth-i, y+bmpHeight); 
+    } else if  (tft.getRotation() == 0) {
+      tft.goTo(x+bmpWidth, y+i); 
+    }
+    
+    for (j=0; j<bmpWidth; j++) {
+      // read more pixels
+      if (buffidx >= 3*BUFFPIXEL) {
+        bmpFile.read(sdbuffer, 3*BUFFPIXEL);
+        buffidx = 0;
+      }
+      
+      // convert pixel from 888 to 565
+      b = sdbuffer[buffidx++];     // blue
+      g = sdbuffer[buffidx++];     // green
+      p = sdbuffer[buffidx++];     // red
+      
+      p >>= 3;
+      p <<= 6;
+      
+      g >>= 2;
+      p |= g;
+      p <<= 5;
+      
+      b >>= 3;
+      p |= b;
+     
+       // write out the 16 bits of color
+      tft.writeData(p);
+    }
+  }
+  Serial.print(millis() - time, DEC);
+  Serial.println(" ms");
+}
+
+boolean bmpReadHeader(File f) {
+   // read header
+  uint32_t tmp;
+  
+  if (read16(f) != 0x4D42) {
+    // magic bytes missing
+    return false;
+  }
+ 
+  // read file size
+  tmp = read32(f);  
+  Serial.print("size 0x"); Serial.println(tmp, HEX);
+  
+  // read and ignore creator bytes
+  read32(f);
+  
+  bmpImageoffset = read32(f);  
+  Serial.print("offset "); Serial.println(bmpImageoffset, DEC);
+  
+  // read DIB header
+  tmp = read32(f);
+  Serial.print("header size "); Serial.println(tmp, DEC);
+  bmpWidth = read32(f);
+  bmpHeight = read32(f);
+
+  
+  if (read16(f) != 1)
+    return false;
+    
+  bmpDepth = read16(f);
+  Serial.print("bitdepth "); Serial.println(bmpDepth, DEC);
+
+  if (read32(f) != 0) {
+    // compression not supported!
+    return false;
+  }
+  
+  Serial.print("compression "); Serial.println(tmp, DEC);
+
+  return true;
+}
+
+/*********************************************/
+
+// These read data from the SD card file and convert them to big endian 
+// (the data is stored in little endian format!)
+
+// LITTLE ENDIAN!
+uint16_t read16(File f) {
+  uint16_t d;
+  uint8_t b;
+  b = f.read();
+  d = f.read();
+  d <<= 8;
+  d |= b;
+  return d;
+}
+
+
+// LITTLE ENDIAN!
+uint32_t read32(File f) {
+  uint32_t d;
+  uint16_t b;
+ 
+  b = read16(f);
+  d = read16(f);
+  d <<= 16;
+  d |= b;
+  return d;
+}
+
Add a comment to this file

Adafruit_TFTLCD-Library/examples/tftbmp/woof.bmp

Added
New image

Adafruit_TFTLCD-Library/examples/tftbmp_shield/tftbmp_shield.pde

+#include <Adafruit_GFX.h>    // Core graphics library
+#include <Adafruit_TFTLCD.h> // Hardware-specific library
+#include <SD.h>
+#include <SPI.h>
+
+#if not defined USE_ADAFRUIT_SHIELD_PINOUT 
+ #error "For use with the shield, make sure to #define USE_ADAFRUIT_SHIELD_PINOUT in the TFTLCD.h library file"
+#endif
+
+// These are the pins as connected in the shield
+#define LCD_CS A3    // Chip Select goes to Analog 3
+#define LCD_CD A2    // Command/Data goes to Analog 2
+#define LCD_WR A1    // LCD Write goes to Analog 1
+#define LCD_RD A0    // LCD Read goes to Analog 0
+
+// The chip select pin for the SD card on the shield
+#define SD_CS 5 
+// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
+// There are examples in the sketch folder
+
+// our TFT wiring
+Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, 0);
+
+// the file itself
+File bmpFile;
+
+// information we extract about the bitmap file
+int bmpWidth, bmpHeight;
+uint8_t bmpDepth, bmpImageoffset;
+
+/************* HARDWARE SPI ENABLE/DISABLE */
+// we want to reuse the pins for the SD card and the TFT - to save 2 pins. this means we have to
+// enable the SPI hardware interface whenever accessing the SD card and then disable it when done
+int8_t saved_spimode;
+
+void disableSPI(void) {
+  saved_spimode = SPCR;
+  SPCR = 0;
+}
+
+void enableSPI(void) {
+  SPCR = saved_spimode; 
+}
+/******************************************/
+
+uint16_t identifier;
+void setup()
+{
+
+  Serial.begin(9600);
+  
+  tft.reset();
+  
+  // find the TFT display
+  identifier = tft.readRegister(0x0);
+  if (identifier == 0x9325) {
+    Serial.println("Found ILI9325");
+  } else if (identifier == 0x9328) {
+    Serial.println("Found ILI9328");
+  } else if (identifier == 0x7575) {
+    Serial.println("Found HX8347G");
+  } else {
+    Serial.print("Unknown driver chip ");
+    Serial.println(identifier, HEX);
+    while (1);
+  }  
+ 
+  tft.begin(identifier);
+  // the image is a landscape, so get into landscape mode
+  tft.setRotation(1);
+  
+  Serial.print("Initializing SD card...");
+ 
+  if (!SD.begin(SD_CS)) {
+    Serial.println("failed!");
+    return;
+  }
+  Serial.println("SD OK!");
+  
+  bmpFile = SD.open("tiger.bmp");
+
+  if (! bmpFile) {
+    Serial.println("didnt find image");
+    while (1);
+  }
+  
+  if (! bmpReadHeader(bmpFile)) { 
+     Serial.println("bad bmp");
+     return;
+  }
+  
+  Serial.print("image size "); 
+  Serial.print(bmpWidth, DEC);
+  Serial.print(", ");
+  Serial.println(bmpHeight, DEC);
+  disableSPI();    // release SPI so we can use those pins to draw
+ 
+  bmpdraw(bmpFile, 0, 0);
+  // disable the SD card interface after we are done!
+  disableSPI();
+}
+
+
+void loop()
+{
+
+}
+
+/*********************************************/
+// This procedure reads a bitmap and draws it to the screen
+// its sped up by reading many pixels worth of data at a time
+// instead of just one pixel at a time. increading the buffer takes
+// more RAM but makes the drawing a little faster. 20 pixels' worth
+// is probably a good place
+
+#define BUFFPIXEL 20
+
+void bmpdraw(File f, int x, int y) {
+
+  enableSPI();     // enable the hardware SPI to talk to the SD card
+  bmpFile.seek(bmpImageoffset);
+  disableSPI();    // release it so we can use those pins
+  
+  uint32_t time = millis();
+  uint16_t p;
+  uint8_t g, b;
+  int i, j;
+  
+  uint8_t sdbuffer[3 * BUFFPIXEL];  // 3 * pixels to buffer
+  uint8_t buffidx = 3*BUFFPIXEL;
+  
+  Serial.print("rotation = "); Serial.println(tft.getRotation(), DEC);
+  
+  for (i=0; i< bmpHeight; i++) {
+    // bitmaps are stored with the BOTTOM line first so we have to move 'up'
+
+    if ((identifier == 0x9325) || (identifier == 0x9328)) {
+      if (tft.getRotation() == 3) {
+        tft.writeRegister16(ILI932X_ENTRY_MOD, 0x1028);
+        tft.goTo(x+i, y); 
+      } else if  (tft.getRotation() == 2) {
+        tft.writeRegister16(ILI932X_ENTRY_MOD, 0x1020);
+        tft.goTo(x+bmpWidth, y+i); 
+      } else if  (tft.getRotation() == 1) {
+        tft.writeRegister16(ILI932X_ENTRY_MOD, 0x1018);
+        tft.goTo(x+bmpHeight-1-i, y); 
+      } else if  (tft.getRotation() == 0) {
+        tft.writeRegister16(ILI932X_ENTRY_MOD, 0x1030);
+        tft.goTo(x, y+bmpHeight-i); 
+      }
+    } else if (identifier == 0x7575) {
+      if (tft.getRotation() == 3) {
+        tft.writeRegister8(HX8347G_MEMACCESS, 0x20);
+        tft.setWindow(x, y+i, 319, y+i); 
+      } else if  (tft.getRotation() == 2) {
+        tft.writeRegister8(HX8347G_MEMACCESS, 0x40);
+        tft.goTo(x, y+i); 
+      } else if  (tft.getRotation() == 1) {
+        tft.writeRegister8(HX8347G_MEMACCESS, 0xA0);
+        tft.setWindow(x, y+bmpHeight-1-i, 319, y+bmpHeight-i); 
+      } else if  (tft.getRotation() == 0) {
+        tft.writeRegister8(HX8347G_MEMACCESS, 0x0);
+        tft.goTo(x, y+bmpHeight-i-1); 
+      }
+    }
+
+    
+    for (j=0; j<bmpWidth; j++) {
+      // read more pixels
+      if (buffidx >= 3*BUFFPIXEL) {
+        enableSPI();     // enable the hardware SPI to talk to the SD card
+        bmpFile.read(sdbuffer, 3*BUFFPIXEL);
+        disableSPI();    // release it so we can use those pins
+        buffidx = 0;
+      }
+      
+      // convert pixel from 888 to 565
+      b = sdbuffer[buffidx++];     // blue
+      g = sdbuffer[buffidx++];     // green
+      p = sdbuffer[buffidx++];     // red
+      
+      p >>= 3;
+      p <<= 6;
+      
+      g >>= 2;
+      p |= g;
+      p <<= 5;
+      
+      b >>= 3;
+      p |= b;
+     
+      // write out the 16 bits of color
+      tft.writeData(p);
+    }
+  }
+  if (identifier == 0x7575) tft.writeRegister8(HX8347G_MEMACCESS, 0x0);
+  else  tft.writeRegister16(ILI932X_ENTRY_MOD, 0x1030);
+  Serial.print(millis() - time, DEC);
+  Serial.println(" ms");
+}
+
+boolean bmpReadHeader(File f) {
+   // read header