ST7735_t3 and Adafruit 0.96" 160x80 Color TFT Display?

Status
Not open for further replies.

barclay

Member
I'm wondering if anyone has gotten the mini-tft featherwing tft working with teensy. Specifically, teensy 3.6 with:
https://www.adafruit.com/product/3321

Based on the ST7735_t3, it looks like there needs to be support for a different width and/or height, but I'm not sure what else would need to be changed. Has anyone looked at this?

Thanks,
-B
 
Looks like the following *might* be all that's needed; I'll give it a try later tonight.

$ pwd
/Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Adafruit_ST7735
$ cat mini.patch
--- Adafruit_ST7735.h 2018-12-07 12:14:07.000000000 -0800
+++ ../Adafruit_ST7735.bak/Adafruit_ST7735.h 2018-11-28 17:28:18.000000000 -0800
@@ -43,10 +43,8 @@
#define INITR_GREENTAB 0x0
#define INITR_REDTAB 0x1
#define INITR_BLACKTAB 0x2
-#define INITR_MINI160x80 0x04

#define ST7735_TFTWIDTH 128
-#define ST7735_TFTWIDTH_80 80 // for mini
#define ST7735_TFTHEIGHT 160

#define ST7735_NOP 0x00
@@ -105,15 +103,6 @@
#define ST7735_YELLOW 0xFFE0
#define ST7735_WHITE 0xFFFF

-#define ST77XX_BLACK 0x0000
-#define ST77XX_BLUE 0x001F
-#define ST77XX_RED 0xF800
-#define ST77XX_GREEN 0x07E0
-#define ST77XX_CYAN 0x07FF
-#define ST77XX_MAGENTA 0xF81F
-#define ST77XX_YELLOW 0xFFE0
-#define ST77XX_WHITE 0xFFFF
-

class Adafruit_ST7735 : public Adafruit_GFX {
--- Adafruit_ST7735.cpp 2018-12-07 12:14:58.000000000 -0800
+++ ../Adafruit_ST7735.bak/Adafruit_ST7735.cpp 2018-11-28 17:28:18.000000000 -0800
@@ -458,16 +458,6 @@
ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay:
0x00, 0x01, // XSTART = 0
0x00, 0x9F+0x01 }, // XEND = 159
-
- Rcmd2green160x80[] = { // 7735R init, part 2 (mini 160x80)
- 2, // 2 commands in list:
- ST7735_CASET , 4, // 1: Column addr set, 4 args, no delay:
- 0x00, 0x00, // XSTART = 0
- 0x00, 0x7F, // XEND = 79
- ST7735_RASET , 4, // 2: Row addr set, 4 args, no delay:
- 0x00, 0x00, // XSTART = 0
- 0x00, 0x9F }, // XEND = 159
-
Rcmd2red[] = { // Init for 7735R, part 2 (red tab only)
2, // 2 commands in list:
ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay:
@@ -711,11 +701,6 @@
commandList(Rcmd2green);
colstart = 2;
rowstart = 1;
- } else if(options == INITR_MINI160x80) {
- _width = ST7735_TFTWIDTH_80;
- commandList(Rcmd2green160x80);
- colstart = 24;
- rowstart = 0;
} else {
// colstart, rowstart left at default '0' values
commandList(Rcmd2red);
 
I'm wondering if anyone has gotten the mini-tft featherwing tft working with teensy. Specifically, teensy 3.6 with:
https://www.adafruit.com/product/3321

Based on the ST7735_t3, it looks like there needs to be support for a different width and/or height, but I'm not sure what else would need to be changed. Has anyone looked at this?

Thanks,
-B

Unfortunately, the Teensy version of ST7735 is rather old. When I last looked at it, the Teensy version was taken from the December 2013 version.

The next change in the Adafruit sources (Sep 5, 2014 to add 128x128 displays) is not in the Teensy sources.

In Sep 2, 2017 they did a major re-organization, adding support for Adafruit_ST7789 as a separate device, and both 7735/7789 calling into common 77xx files.

Note, with the current Adafruit sources, if you don't take the Teensy version of Adafruit_ST7735, and instead take the current version from Adafruit, it won't build, because the current Adafruit ST7735 depends on recent changes to Adafruit_GFX, so you need to grab that as well. At the moment, I have the September 5th, 2014 version in my tree and I have renamed it for the one application that wants to do 128x128 TFT displays.

I have not yet installed 1.45 beta1, so I can't say if things are any better.

 
Last edited:
Thanks for the detailed response. Do you know if the ABI is still compatible, e.g., can I just swap out /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Adafruit_ST7735 and /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Adafruit_GFX with the current versions from Adafruit, or will there be issues with the UTFT/tft_drivers/st7735* drivers due to that?

-B
 
Thanks for the detailed response. Do you know if the ABI is still compatible, e.g., can I just swap out /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Adafruit_ST7735 and /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Adafruit_GFX with the current versions from Adafruit, or will there be issues with the UTFT/tft_drivers/st7735* drivers due to that?

-B

I've done it for testing purposes on my 128x128 display, and it seemed to work, but note the program I used (uncanny eyes) mainly uses it for the setup, and it does most of its own screen updates. I think I ran the standard example test program. Note, the standard example test program just uses the standard calls and GFX. I don't think it uses the UTFT drivers. I will try to run it tonight.

I have a separate Teensy installation direction with those two files replaced with the Adafruit versions.

Obviously, you will not get the speed-ups that Paul added to the driver if you use the special hardware CS pins for CS and DC.
 
I've done it for testing purposes on my 128x128 display, and it seemed to work, but note the program I used (uncanny eyes) mainly uses it for the setup, and it does most of its own screen updates. I think I ran the standard example test program. Note, the standard example test program just uses the standard calls and GFX. I don't think it uses the UTFT drivers. I will try to run it tonight.

I have a separate Teensy installation direction with those two files replaced with the Adafruit versions.

Obviously, you will not get the speed-ups that Paul added to the driver if you use the special hardware CS pins for CS and DC.

Cool, I'll try that tonight if I get a chance. I'm not too worried about losing the speed optimizations -- I'm using the M4F on 3.6 for the FPU to speed up quaternion calculations; screen updates don't really need to be any fast than ~1-2 times/second. And, with the amount of RAM on the 3.6, I should be able to double-buffer the entire screen if I want, such that the screen update is "atomic". Hopefully (fingers crossed) the Adafruit libs aren't horribly slow for blitting the whole thing, but if it is, I supposed I'll just do area updates, else wait for the teensy distro to be updated. :) (Or see if I can find the time to do it myself?)

Thanks again, I'll let you know if it works for me!

-B
 
FWIW, here is the thread that talks about the optimizations for the ILI9341. I believe this is the basis for the other display drivers that were similarly modified:

I did test this on my Teensy 3.2 which has 2 TFT 128x128 displays setup for the uncanny eyes program. The test is the example program, modified to use the pins I use for uncanny eyes, and to print out the elapsed time, etc. It is interesting that the native Adafruit version is faster than the Teensy version by 0.6 seconds (out of 21-22 seconds). I originally thought this was due to the fact that the native version uses a 128x128 display and the Teensy did 128x160, so I commented out the part that used the 128x128 initialization, and both did 128x160. In doing so, it made the Adafruit version 0.1 second slower, but it is still 0.5 seconds faster than the Teensy optimized version was. I tested it with various compile options (Faster, Fastest + pure code, Fastest + pure code + LTO), and also tried overclocking it to 120Mhz.

I suspect you need to have a larger screen like the ILI9341 to see the speed-ups. Or else, you need to restructure the code, so that it can do independent calculations while the DMA is blitting to the screen (this might be where double buffering would help):

Code:
/***************************************************
  This is an example sketch for the Adafruit 1.8" SPI display.
  This library works with the Adafruit 1.8" TFT Breakout w/SD card
  ----> http://www.adafruit.com/products/358
  as well as Adafruit raw 1.8" TFT display
  ----> http://www.adafruit.com/products/618
 
  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 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
 ****************************************************/

// This Teensy3 native optimized version requires specific pins
//
#if 0
//#define sclk	13	// SCLK can also use pin 14
//#define mosi	11	// MOSI can also use pin 7
#define cs	10	// CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define dc	A1	//  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define rst	8	// RST can use any pin
#define sdcs	4	// CS for SD card, can use any pin

// use the pins for meissner's teensy eyes setup
#else
//#define sclk	13	// SCLK can also use pin 14
//#define mosi	11	// MOSI can also use pin 7
#define cs	A8	// CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define dc	A1	//  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define rst	A0	// RST can use any pin
#define sdcs	4	// CS for SD card, can use any pin
#endif

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>

#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

// Option 1: use any pins but a little slower
//Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);

// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
float p = 3.1415926;

 
#define Neutral 0
#define Press 1
#define Up 2
#define Down 3
#define Right 4
#define Left 5
 
// Check the joystick position
int CheckJoystick()
{
  int joystickState = analogRead(3);
  
  if (joystickState < 50) return Left;
  if (joystickState < 150) return Down;
  if (joystickState < 250) return Press;
  if (joystickState < 500) return Right;
  if (joystickState < 650) return Up;
  return Neutral;
}


void setup(void) {
  pinMode(sdcs, INPUT_PULLUP);  // don't touch the SD card
  while (!Serial && millis () < 4000UL)
    ;
  Serial.begin(9600);
  Serial.println("hello!");
  delay(5000);

  // Our supplier changed the 1.8" display slightly after Jan 10, 2012
  // so that the alignment of the TFT had to be shifted by a few pixels
  // this just means the init code is slightly different. Check the
  // color of the tab to see which init code to try. If the display is
  // cut off or has extra 'random' pixels on the top & left, try the
  // other option!
  // If you are seeing red and green color inversion, use Black Tab

  // If your TFT's plastic wrap has a Black Tab, use the following:
  //tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
  // If your TFT's plastic wrap has a Red Tab, use the following:
  //tft.initR(INITR_REDTAB);   // initialize a ST7735R chip, red tab
  // If your TFT's plastic wrap has a Green Tab, use the following:
  //tft.initR(INITR_GREENTAB); // initialize a ST7735R chip, green tab

#ifdef INITR_144GREENTAB
  tft.initR(INITR_144GREENTAB);	// initialize a ST7735R chip with 128x128 display, green tab
#else
  tft.initR(INITR_GREENTAB);	// initialize a ST7735R chip, green tab
#endif

  Serial.print("init, width = ");
  Serial.print(tft.width ());
  Serial.print(", height = ");
  Serial.println(tft.height ());

  uint16_t time = millis();
  tft.fillScreen(ST7735_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  Serial.println ("Text");
  tft.fillScreen(ST7735_BLACK);
  char text_output[] =	"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
			"Curabitur adipiscing ante sed nibh tincidunt feugiat. "
			"Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. "
			"Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. "
			"Nullam aliquet ultrices massa eu hendrerit. "
			"Ut sed nisi lorem. "
			"In vestibulum purus a tortor imperdiet posuere. ";
  testdrawtext(text_output, ST7735_WHITE);
  delay(1000);

  // tft print function!
  Serial.println ("PrintTest");
  tftPrintTest();
  delay(4000);

  // a single pixel
  Serial.println ("DrawPixel");
  tft.drawPixel(tft.width()/2, tft.height()/2, ST7735_GREEN);
  delay(500);

  // line draw test
  Serial.println ("TestLines");
  testlines(ST7735_YELLOW);
  delay(500);

  // optimized lines
  Serial.println ("FastLines");
  testfastlines(ST7735_RED, ST7735_BLUE);
  delay(500);

  Serial.println ("DrawRects");
  testdrawrects(ST7735_GREEN);
  delay(500);

  Serial.println ("FillRects");
  testfillrects(ST7735_YELLOW, ST7735_MAGENTA);
  delay(500);

  Serial.println ("Circles");
  tft.fillScreen(ST7735_BLACK);
  testfillcircles(10, ST7735_BLUE);
  testdrawcircles(10, ST7735_WHITE);
  delay(500);

  Serial.println ("Roundrects");
  testroundrects();
  delay(500);

  Serial.println ("Triangles");
  testtriangles();
  delay(500);

  Serial.println ("Buttons");
  mediabuttons();
  delay(500);

  Serial.print("done, ");
  unsigned long m = millis ();
  Serial.print(m / 1000u);
  m %= 1000u;
  Serial.print ('.');
  if (m < 10) {
    Serial.print ("00");
  } else if (m < 100) {
    Serial.print ("0");
  }
  Serial.print (m);
  Serial.println ( " seconds");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);
}

void testlines(uint16_t color) {
  tft.fillScreen(ST7735_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(ST7735_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(ST7735_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(ST7735_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 testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST7735_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 testdrawrects(uint16_t color) {
  tft.fillScreen(ST7735_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 testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=tft.width()-1; x > 6; x-=6) {
    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 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 testtriangles() {
  tft.fillScreen(ST7735_BLACK);
  int color = 0xF800;
  int t;
  int w = 63;
  int x = 159;
  int y = 0;
  int z = 127;
  for(t = 0 ; t <= 15; t+=1) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x-=4;
    y+=4;
    z-=4;
    color+=100;
  }
}

void testroundrects() {
  tft.fillScreen(ST7735_BLACK);
  int color = 100;
  int i;
  int t;
  for(t = 0 ; t <= 4; t+=1) {
    int x = 0;
    int y = 0;
    int w = 127;
    int h = 159;
    for(i = 0 ; i <= 24; i+=1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
      x+=2;
      y+=3;
      w-=4;
      h-=6;
      color+=1100;
    }
    color+=100;
  }
}

void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST7735_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST7735_BLACK);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi?");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST7735_WHITE);
  tft.println("Sketch has been");
  tft.println("running for: ");
  tft.setTextColor(ST7735_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST7735_WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(ST7735_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST7735_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST7735_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_GREEN);
}


// HISTORY
// $Log: St7735_128x128.ino,v $
// Revision 1.6  2018/10/07 22:01:40  michaelmeissner
// Fixup printing seconds
//
// Revision 1.5  2018/10/07 21:56:09  michaelmeissner
// Print ms at the end.
//
// Revision 1.4  2018/10/07 21:26:24  michaelmeissner
// Switch to use pins from meissner's version of uncanny eyes
//
// Revision 1.3  2016/11/26 20:41:07  michaelmeissner
// Wait for 5 seconds at init; Add print statements before each test.
//
// Revision 1.2  2016/11/26 17:50:01  michaelmeissner
// Automaticaly select INITR_144GREENTAB if it is available; print width/height.
//
// Revision 1.1  2016/10/24 13:53:10  michaelmeissner
// Initial version.
//
 
I also tested the Teensy specific ST7735_t3 library with slightly modified code. It looks like it runs 1.5 seconds faster than the Adafruit_ST7735 library with Teensy modifications and 1 second faster than the Adafruit_ST7735 from Adafruit:

Code:
/***************************************************
  This is an example sketch for the Adafruit 1.8" SPI display.

This library works with the Adafruit 1.8" TFT Breakout w/SD card
  ----> http://www.adafruit.com/products/358
The 1.8" TFT shield
  ----> https://www.adafruit.com/product/802
The 1.44" TFT breakout
  ----> https://www.adafruit.com/product/2088
as well as Adafruit raw 1.8" TFT display
  ----> http://www.adafruit.com/products/618

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 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
 ****************************************************/

// This Teensy3 native optimized version requires specific pins
//
#if 0
#define TFT_SCLK 13	// SCLK can also use pin 14
#define TFT_MOSI 11	// MOSI can also use pin 7
#define TFT_CS   10	// CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
//#define TFT_DC    9	//  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_DC   A1	//  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   8	// RST can use any pin
#define SD_CS     4	// CS for SD card, can use any pin

// use the pins for meissner's teensy eyes setup
#else
#define TFT_SCLK 13	// SCLK can also use pin 14
#define TFT_MOSI 11	// MOSI can also use pin 7
#define TFT_CS	A8	// CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC	A1	//  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST	A0	// RST can use any pin
#define SD_CS	4	// CS for SD card, can use any pin
#endif

#include <Adafruit_GFX.h>    // Core graphics library
#include <ST7735_t3.h> // Hardware-specific library
#include <SPI.h>

// Option 1: use any pins but a little slower
//ST7735_t3 tft = ST7735_t3(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
ST7735_t3 tft = ST7735_t3(TFT_CS, TFT_DC, TFT_RST);
float p = 3.1415926;

 
#define Neutral 0
#define Press 1
#define Up 2
#define Down 3
#define Right 4
#define Left 5
 
// Check the joystick position
int CheckJoystick()
{
  int joystickState = analogRead(3);
  
  if (joystickState < 50) return Left;
  if (joystickState < 150) return Down;
  if (joystickState < 250) return Press;
  if (joystickState < 500) return Right;
  if (joystickState < 650) return Up;
  return Neutral;
}


void setup(void) {
  pinMode(SD_CS, INPUT_PULLUP);  // don't touch the SD card
  while (!Serial && millis () < 4000UL)
    ;
  Serial.begin(9600);
  Serial.println("hello!");
  delay(5000);

  // Use this initializer if you're using a 1.8" TFT
  //tft.initR(INITR_BLACKTAB);
  // Use this initializer (uncomment) if you're using a 1.44" TFT
  //tft.initR(INITR_144GREENTAB);
#ifdef INITR_144GREENTAB
  tft.initR(INITR_144GREENTAB);	// initialize a ST7735R chip with 128x128 display, green tab
#else
  tft.initR(INITR_GREENTAB);	// initialize a ST7735R chip, green tab
#endif

  Serial.print("init, width = ");
  Serial.print(tft.width ());
  Serial.print(", height = ");
  Serial.println(tft.height ());

  uint16_t time = millis();
  tft.fillScreen(ST7735_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  Serial.println ("Text");
  tft.fillScreen(ST7735_BLACK);
  char text_output[] =	"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
			"Curabitur adipiscing ante sed nibh tincidunt feugiat. "
			"Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. "
			"Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. "
			"Nullam aliquet ultrices massa eu hendrerit. "
			"Ut sed nisi lorem. "
			"In vestibulum purus a tortor imperdiet posuere. ";
  testdrawtext(text_output, ST7735_WHITE);
  delay(1000);

  // tft print function!
  Serial.println ("PrintTest");
  tftPrintTest();
  delay(4000);

  // a single pixel
  Serial.println ("DrawPixel");
  tft.drawPixel(tft.width()/2, tft.height()/2, ST7735_GREEN);
  delay(500);

  // line draw test
  Serial.println ("TestLines");
  testlines(ST7735_YELLOW);
  delay(500);

  // optimized lines
  Serial.println ("FastLines");
  testfastlines(ST7735_RED, ST7735_BLUE);
  delay(500);

  Serial.println ("DrawRects");
  testdrawrects(ST7735_GREEN);
  delay(500);

  Serial.println ("FillRects");
  testfillrects(ST7735_YELLOW, ST7735_MAGENTA);
  delay(500);

  Serial.println ("Circles");
  tft.fillScreen(ST7735_BLACK);
  testfillcircles(10, ST7735_BLUE);
  testdrawcircles(10, ST7735_WHITE);
  delay(500);

  Serial.println ("Roundrects");
  testroundrects();
  delay(500);

  Serial.println ("Triangles");
  testtriangles();
  delay(500);

  Serial.println ("Buttons");
  mediabuttons();
  delay(500);

  Serial.print("done, ");
  unsigned long m = millis ();
  Serial.print(m / 1000u);
  m %= 1000u;
  Serial.print ('.');
  if (m < 10) {
    Serial.print ("00");
  } else if (m < 100) {
    Serial.print ("0");
  }
  Serial.print (m);
  Serial.println ( " seconds");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);
}

void testlines(uint16_t color) {
  tft.fillScreen(ST7735_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(ST7735_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(ST7735_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(ST7735_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 testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST7735_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 testdrawrects(uint16_t color) {
  tft.fillScreen(ST7735_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 testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=tft.width()-1; x > 6; x-=6) {
    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 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 testtriangles() {
  tft.fillScreen(ST7735_BLACK);
  int color = 0xF800;
  int t;
  int w = 63;
  int x = 159;
  int y = 0;
  int z = 127;
  for(t = 0 ; t <= 15; t+=1) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x-=4;
    y+=4;
    z-=4;
    color+=100;
  }
}

void testroundrects() {
  tft.fillScreen(ST7735_BLACK);
  int color = 100;
  int i;
  int t;
  for(t = 0 ; t <= 4; t+=1) {
    int x = 0;
    int y = 0;
    int w = 127;
    int h = 159;
    for(i = 0 ; i <= 24; i+=1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
      x+=2;
      y+=3;
      w-=4;
      h-=6;
      color+=1100;
    }
    color+=100;
  }
}

void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST7735_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST7735_BLACK);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi?");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST7735_WHITE);
  tft.println("Sketch has been");
  tft.println("running for: ");
  tft.setTextColor(ST7735_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST7735_WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(ST7735_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST7735_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST7735_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_GREEN);
}


// HISTORY
// $Log: St7735_128x128_t3.ino,v $
// Revision 1.4  2018/12/08 06:19:18  michaelmeissner
// Incorporate changes from St7735_128x128.ino.
//
// Revision 1.3  2016/11/26 20:42:02  michaelmeissner
// Rebase to use graphicstest example; Add initial delay; Add print statements before each test.
//
// Revision 1.2  2016/11/26 17:50:15  michaelmeissner
// Automaticaly select INITR_144GREENTAB if it is available; print width/height.
//
// Revision 1.1  2016/11/26 02:01:21  michaelmeissner
// Initial version, clone from St7735_128x128.
 
I also tested the Teensy specific ST7735_t3 library with slightly modified code. It looks like it runs 1.5 seconds faster than the Adafruit_ST7735 library with Teensy modifications and 1 second faster than the Adafruit_ST7735 from Adafruit:

Code:
/***************************************************
  This is an example sketch for the Adafruit 1.8" SPI display.

This library works with the Adafruit 1.8" TFT Breakout w/SD card
  ----> http://www.adafruit.com/products/358
The 1.8" TFT shield
  ----> https://www.adafruit.com/product/802
The 1.44" TFT breakout
  ----> https://www.adafruit.com/product/2088
as well as Adafruit raw 1.8" TFT display
  ----> http://www.adafruit.com/products/618

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 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
 ****************************************************/

// This Teensy3 native optimized version requires specific pins
//
#if 0
#define TFT_SCLK 13	// SCLK can also use pin 14
#define TFT_MOSI 11	// MOSI can also use pin 7
#define TFT_CS   10	// CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
//#define TFT_DC    9	//  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_DC   A1	//  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   8	// RST can use any pin
#define SD_CS     4	// CS for SD card, can use any pin

// use the pins for meissner's teensy eyes setup
#else
#define TFT_SCLK 13	// SCLK can also use pin 14
#define TFT_MOSI 11	// MOSI can also use pin 7
#define TFT_CS	A8	// CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC	A1	//  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST	A0	// RST can use any pin
#define SD_CS	4	// CS for SD card, can use any pin
#endif

#include <Adafruit_GFX.h>    // Core graphics library
#include <ST7735_t3.h> // Hardware-specific library
#include <SPI.h>

// Option 1: use any pins but a little slower
//ST7735_t3 tft = ST7735_t3(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
ST7735_t3 tft = ST7735_t3(TFT_CS, TFT_DC, TFT_RST);
float p = 3.1415926;

 
#define Neutral 0
#define Press 1
#define Up 2
#define Down 3
#define Right 4
#define Left 5
 
// Check the joystick position
int CheckJoystick()
{
  int joystickState = analogRead(3);
  
  if (joystickState < 50) return Left;
  if (joystickState < 150) return Down;
  if (joystickState < 250) return Press;
  if (joystickState < 500) return Right;
  if (joystickState < 650) return Up;
  return Neutral;
}


void setup(void) {
  pinMode(SD_CS, INPUT_PULLUP);  // don't touch the SD card
  while (!Serial && millis () < 4000UL)
    ;
  Serial.begin(9600);
  Serial.println("hello!");
  delay(5000);

  // Use this initializer if you're using a 1.8" TFT
  //tft.initR(INITR_BLACKTAB);
  // Use this initializer (uncomment) if you're using a 1.44" TFT
  //tft.initR(INITR_144GREENTAB);
#ifdef INITR_144GREENTAB
  tft.initR(INITR_144GREENTAB);	// initialize a ST7735R chip with 128x128 display, green tab
#else
  tft.initR(INITR_GREENTAB);	// initialize a ST7735R chip, green tab
#endif

  Serial.print("init, width = ");
  Serial.print(tft.width ());
  Serial.print(", height = ");
  Serial.println(tft.height ());

  uint16_t time = millis();
  tft.fillScreen(ST7735_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  Serial.println ("Text");
  tft.fillScreen(ST7735_BLACK);
  char text_output[] =	"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
			"Curabitur adipiscing ante sed nibh tincidunt feugiat. "
			"Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. "
			"Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. "
			"Nullam aliquet ultrices massa eu hendrerit. "
			"Ut sed nisi lorem. "
			"In vestibulum purus a tortor imperdiet posuere. ";
  testdrawtext(text_output, ST7735_WHITE);
  delay(1000);

  // tft print function!
  Serial.println ("PrintTest");
  tftPrintTest();
  delay(4000);

  // a single pixel
  Serial.println ("DrawPixel");
  tft.drawPixel(tft.width()/2, tft.height()/2, ST7735_GREEN);
  delay(500);

  // line draw test
  Serial.println ("TestLines");
  testlines(ST7735_YELLOW);
  delay(500);

  // optimized lines
  Serial.println ("FastLines");
  testfastlines(ST7735_RED, ST7735_BLUE);
  delay(500);

  Serial.println ("DrawRects");
  testdrawrects(ST7735_GREEN);
  delay(500);

  Serial.println ("FillRects");
  testfillrects(ST7735_YELLOW, ST7735_MAGENTA);
  delay(500);

  Serial.println ("Circles");
  tft.fillScreen(ST7735_BLACK);
  testfillcircles(10, ST7735_BLUE);
  testdrawcircles(10, ST7735_WHITE);
  delay(500);

  Serial.println ("Roundrects");
  testroundrects();
  delay(500);

  Serial.println ("Triangles");
  testtriangles();
  delay(500);

  Serial.println ("Buttons");
  mediabuttons();
  delay(500);

  Serial.print("done, ");
  unsigned long m = millis ();
  Serial.print(m / 1000u);
  m %= 1000u;
  Serial.print ('.');
  if (m < 10) {
    Serial.print ("00");
  } else if (m < 100) {
    Serial.print ("0");
  }
  Serial.print (m);
  Serial.println ( " seconds");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);
}

void testlines(uint16_t color) {
  tft.fillScreen(ST7735_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(ST7735_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(ST7735_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(ST7735_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 testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST7735_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 testdrawrects(uint16_t color) {
  tft.fillScreen(ST7735_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 testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=tft.width()-1; x > 6; x-=6) {
    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 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 testtriangles() {
  tft.fillScreen(ST7735_BLACK);
  int color = 0xF800;
  int t;
  int w = 63;
  int x = 159;
  int y = 0;
  int z = 127;
  for(t = 0 ; t <= 15; t+=1) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x-=4;
    y+=4;
    z-=4;
    color+=100;
  }
}

void testroundrects() {
  tft.fillScreen(ST7735_BLACK);
  int color = 100;
  int i;
  int t;
  for(t = 0 ; t <= 4; t+=1) {
    int x = 0;
    int y = 0;
    int w = 127;
    int h = 159;
    for(i = 0 ; i <= 24; i+=1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
      x+=2;
      y+=3;
      w-=4;
      h-=6;
      color+=1100;
    }
    color+=100;
  }
}

void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST7735_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST7735_BLACK);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi?");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST7735_WHITE);
  tft.println("Sketch has been");
  tft.println("running for: ");
  tft.setTextColor(ST7735_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST7735_WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(ST7735_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST7735_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST7735_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_GREEN);
}


// HISTORY
// $Log: St7735_128x128_t3.ino,v $
// Revision 1.4  2018/12/08 06:19:18  michaelmeissner
// Incorporate changes from St7735_128x128.ino.
//
// Revision 1.3  2016/11/26 20:42:02  michaelmeissner
// Rebase to use graphicstest example; Add initial delay; Add print statements before each test.
//
// Revision 1.2  2016/11/26 17:50:15  michaelmeissner
// Automaticaly select INITR_144GREENTAB if it is available; print width/height.
//
// Revision 1.1  2016/11/26 02:01:21  michaelmeissner
// Initial version, clone from St7735_128x128.

I haven't had too much time to play around with performance testing, but a quick-n-dirty swap out of the teensy libs with the current Adafruit ones gives me a workable screen. Hopefully I'll get a chance to dig in further in a week or two. Thanks for the pointers!
 
Status
Not open for further replies.
Back
Top