ST7789_t3 (part of ST7735 library) support for displays without CS pin

...
Actually right now I have 3 uncanny eyes setups 8)


2 CS challenged ST7789 son SPI and SPI2 (using Pauls breakout and Sparkfun SDCard breakout board...) - So if someone like Tim or ... with these challenged displays wish to play along:
All post up the current async version of the code with a large eye defined...
...

Which repository for the UncannyEyes for no_CS 7789's? Will be fun to see what has been done on these nice hi res displays … lots of 'learning', work and new bald spots ...
 
@KurtE

Smiling and crying at the same time :)

Copying most of the stuff from your ILI9341_t3n library instead of bodmers. Only thing I cant decide on is if the Adafruit fonts would work or just use Bodmers :)
 
My use two SPI buss version, which as the large eye stuff...

View attachment uncannyEyes_async_st7735-190827a.zip

There is only one eye type based on the default one, which I choose by default if you are using ST7789.

There are a couple of defines at the start.

Code:
#define USE_ASYNC_UPDATES
#define ST77XX_ON_SPI_SPI2
#define USE_ST7789
#define DEBUG_ST7789
The first is the one that turns on using the DMA updates.

The second is my defines for using the SPI2 setup which has the CS challenged displays on it.
And likewise using the ST7789 displays..

Now the debug turn on, actually outputs info at the top and bottom of eye which I am using to help debug. The first number iScale is the thing that is driving the problem I have.
If it is below 400 maybe closer to 700 eye draws wrong. Higher numbers draw better, but Iris is not as big as it should be... So some scaling issue...
 
@mjs513 (@PaulStoffregen) - Sounds good to me... Paul owns the library... So he will be the one who needs to take in the PR's.

Hopefully Paul will grab the current PR for fixing DMA issues when the objects are created in the heap space, before the next teensduino release/beta...

And then you will obviously need to add it now to the SSD1351 stuff ;)

Hopefully he will agree, but I am finding out how much the lib relies on adafruit GFX. Working on moving over most of the functions now. It is a learning experience as always.
 
My use two SPI buss version, which as the large eye stuff...

There is only one eye type based on the default one, which I choose by default if you are using ST7789.

There are a couple of defines at the start.

Code:
#define USE_ASYNC_UPDATES
#define ST77XX_ON_SPI_SPI2
#define USE_ST7789
#define DEBUG_ST7789
The first is the one that turns on using the DMA updates.

The second is my defines for using the SPI2 setup which has the CS challenged displays on it.
And likewise using the ST7789 displays..

Now the debug turn on, actually outputs info at the top and bottom of eye which I am using to help debug. The first number iScale is the thing that is driving the problem I have.
If it is below 400 maybe closer to 700 eye draws wrong. Higher numbers draw better, but Iris is not as big as it should be... So some scaling issue...

Cool. I need to wire up my second Teensy 4 to export at least pins 26 and 27. If I get motivated, hopefully I can run it against the Monster M4SK that I bought. I expect the Teeny 4.0 (M7) is faster than Adafruit M4SK (M4), but it is likely that speed of the SPI bus and the two displays will dominate and they may be at the same speed.

And with two months to go before Halloween, it might be useful to also add sound effects. I've always wanted to incorporate two distance sensors as well, so the eyes track people as they move.

I've discovered if I let any of the uncanny eyes run for a long time, and I see them out of the corner of my eye, it can get a little creepy.

If you don't count soldering, and doing all of the DYI, right now a Teensy 4.0 + 2 of the cheap non-CS displays is a little cheaper than the M4SK (~ $30 US vs. $45 US, not counting s/h).

I am curious how you support many different displays, each with different pinouts. Do you just re-jumper each display as you test it, or do you have a separate Teensy for each display always wired up, or do like I do, have a protoboard that you mount the Teensy of the day (or breadboard) with the SPI pins brought out in a specific order, and then use a custom cable that goes from that standard pinout to the particular display?

Hopefully he will agree, but I am finding out how much the lib relies on adafruit GFX. Working on moving over most of the functions now. It is a learning experience as always.
It may make sense to try and get Adafruit to add the new functions to their library as well. That way people can float between the two libraries.
 
Last edited:
How sweet it is - you just couldn't resist :)

Always the question to myself is should I actually make it fully work?
That is currently the new SSD1351_t3 library appears to be working great on T4 (https://github.com/KurtE/SSD1351_t3), as I mentioned in the simple how many times in a second can it call fillScreen with different colors.

With this library: 72 with Adafruit 48...

So I thought I should at least try on T3.6... And I had compile errors, which I fixed, but the display is not showing up correctly....
The speed test ran and I think it was something like 71 on T3.6
The Adafruit run was 27...

Hooked up Logic Analyzer and output looked correct, BUT: the output at about 20MHZ was too fast, changed the Frequency requested from 24000000 to 19000000 and display works correctly.
So I could go at faster SPI speed on T4 then I could on T3.6, maybe because on T3.6 it is using hardware CS for both CS and DC and on T4 not. So maybe time delay between CS assert or ...

Anyway running with set to 19mhz actual SPI speed about 14.71mhz.
Frames per second 54...

So latest change by default will probably lower speed of T4, but you can now pass in desired frequency on the tft.begin() method...

Again wondering to self: Should we keep making our own Teensy versions of these libraries and/or see if we can integrate some of these speed ups into the Adafruit_GFX (spitft), such that more people can automatically get better performance on the Teensy boards). Of course they probably would not get all of the other stuff, like frame buffer, DMA, additional graphic primitives...
 
@KurtE

Guess that is always the question - Where to stop and say ok the basics are working do we need to expand it to do everything the other displays do. Took a while for me to decide to do that with the ST7789 board. Think the only reason I decided to do it was because (1) the display resolution was 240x320 on the board that I have and (2) was looking for a bit more functionality. So I wound up putting everything in that the ILI9341_t3n lib has as long as I was doing it - argh. But by doing it learned a bit more info.

As for adding in that tft.begin(frequency) I actually think that's a good idea for some of the other libraries as well. Ran into an issue with the arducam where I had to slow down the SPI speed for the display. Then it worked great. May have to add that into the ST7735 lib as well :)

About the wondering: Guess it could work - incorporate the basics of the Teensy speedups you did for adafruit so if you just want to use the adafruit gfx lib its there. If you want to use the additional features like frame buffer, DMA etc you would use the specific Teensy library.
 
Since, Adafruit has its own machines with DMA and they now have an Adafruit_ZeroDMA library that abstracts this in some sense. If we can have the same public names (using a different include file), it may be easier in the future to import things from the Adafruit world to the Teensy world.

I assume by now, we plan to keep the Teensy stuff in a new file, and not trying to keep the Adafruit library up to date with Teensy patches (i.e. the old ST7735 library). Of course from time to time, it will mean we have to update the *_t{3,4} libraries when Adafruit_GFX changes.
 
@KurtE - @defragster

I just created a new repository for my rewrites - haven't tested everything just trying to graphicstest.ino function working first. The only thing that seems to be broke is drawLine function. Other functions in graphicstest seem to be working. Took me so long because of my fat fingers and forgetting I had to change certain things around - argh.

Anyway if you are interested my changes are here: https://github.com/mjs513/ST7735_t3/tree/ST7735_T4_rewrite. Pretty sure I started your Kurt's dma_low branch :)
 
@KurtE - if you tried it I think the problem is with porting clipping over from ILI9341 library

Update: got it solved - now for more testing :)
 
Last edited:
@mjs513 @MichaelMeissner - Sorry I have been MIA this afternoon. Weather is too nice to sit inside and too much beer at lunch.

MISO - Have not been used in constructors as none of the display I have seen use them..... (Except a few of them use them for onboard SD cards...). Could be wrong, but I think these constructors came from the Adafruit stuff.

Have not had a chance to play yet.

Adafruit SPITFT library: I mentioned speed difference up on Adafruit library and got a response back:
From Adafruit2...
we'd love to have teensy 3/4 speedups in SPITFT.cpp, we chatted with paul about this but he got very busy. we did update all our libraries as he requested to use 'transactions' for sending commands and data. there's definitely room for speedups, even if its not as fast as can possibly be :)

The question would be how far to take it...

There are some obvious low hanging fruit like:
Code:
void Adafruit_SPITFT::SPI_WRITE16(uint16_t w) {
    if(connection == TFT_HARD_SPI) {
#if defined(__AVR__)
        AVR_WRITESPI(w >> 8);
        AVR_WRITESPI(w);
#elif defined(ESP8266) || defined(ESP32)
        hwspi._spi->write16(w);
#else
        hwspi._spi->transfer(w >> 8);
        hwspi._spi->transfer(w);
#endif
    } else if(connection == TFT_SOFT_SPI) {
The Teensy should call transfer16 instead of two calls to transfer.

But I think we can also get lots of speedups, either directly going to registers or the like...
 
@KurtE

Glad you enjoyed your day - everybody needs a break sometime :)

As for speed ups. Yes certainly for some boards you can speed up by doing transfer16's but maybe you should consider just exporting what you have been doing with all the display libraries that you have, i.e, use the registers like you said for the Teensies.

On a side note almost got it all working but its like its stuck in 240x240 mode - still think I have to go over all the functions again in case I did anything dumb with the clipping. But at least it passes the graphicstest now.
 
@KurtE

Looks like I fixed the issues with clipping so I think all the graphic primitives are now work - so now trying to work on getting fonts working with the ST7735. But got a strange error associated with SPI that I have no clue how to trace where the problem is in the code unless I forgot to include something - maybe you have seen this before - I apologize for the length:
Code:
Arduino: 1.8.9 (Windows 10), TD: 1.47, Board: "Teensy 4.0, Serial, Faster, US English"

In file included from F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\ST7735_t3.h:23:0,
                 from F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\st7735_t3_font_Arial.h:4,

                 from F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\st7735_t3_font_Arial.c:1:

F:\arduino-1.8.9\hardware\teensy\avr\libraries\SPI/SPI.h:1037:1: error: unknown type name 'class'

 class SPISettings {
 ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\SPI/SPI.h:1037:19: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token

 class SPISettings {
                   ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\SPI/SPI.h:1069:1: error: unknown type name 'class'

 class SPIClass { // Teensy 4
 ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\SPI/SPI.h:1069:16: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token

 class SPIClass { // Teensy 4
                ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\SPI/SPI.h:1378:8: error: unknown type name 'SPIClass'

 extern SPIClass SPI;
        ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\SPI/SPI.h:1383:8: error: unknown type name 'SPIClass'

 extern SPIClass SPI1;
        ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\SPI/SPI.h:1384:8: error: unknown type name 'SPIClass'

 extern SPIClass SPI2;
        ^

In file included from F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\st7735_t3_font_Arial.h:4:0,
                 from F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\st7735_t3_font_Arial.c:1:

F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\ST7735_t3.h:138:3: error: unknown type name 'DMASetting'

   DMASetting      _dmasettings[2];
   ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\ST7735_t3.h:139:3: error: unknown type name 'DMAChannel'

   DMAChannel      _dmatx;
   ^

Error compiling for board Teensy 4.0.
 
@mjs513 - Probably an issue maybe with SPI.h or the like,

Where you are trying to compile in a .c file (C not C++), so in a C file things like: class foo;
is not valid.

In some libraries and the like you will see something like:
#ifdef __cplusplus
All of your c++ stuff
Maybe something like: extern "C" {
...

In SPI.h I don't see any such ifdef stuff...

So simple answer is, a C file and likewise any header file included in a C file should not include SPI.h
 
@KurtE

Glad you enjoyed your day - everybody needs a break sometime :)

As for speed ups. Yes certainly for some boards you can speed up by doing transfer16's but maybe you should consider just exporting what you have been doing with all the display libraries that you have, i.e, use the registers like you said for the Teensies.

On a side note almost got it all working but its like its stuck in 240x240 mode - still think I have to go over all the functions again in case I did anything dumb with the clipping. But at least it passes the graphicstest now.
Actually Lunch out yesterday sort of sucked... The first place we went to was one of our old favorites, which recently sold. The new owners, changed a lot of the food (not for the better) and the server was unfriendly... Which is why we went to another place and had a few more drinks...

Started playing a little with speedups and yes I think the only way to reasonably speed it up is to bring in a lot of the stuff, we have done to talk directly to registers...

I hacked up a copy of the graphic test and added some simple timing outputs:
Code:
#define USE_ADAFRUIT
#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 128 // Change this to 96 for 1.27" OLED.

// You can use any (4 or) 5 pins 
#define SCLK_PIN 13
#define MOSI_PIN 11
#define DC_PIN   9
#define CS_PIN   10
#define RST_PIN  8

// 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


#include <Adafruit_GFX.h>

#include <SPI.h>

#ifdef USE_ADAFRUIT
#include <Adafruit_SSD1351.h>
Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);
#else 
#include <SSD1351_t3.h>
SSD1351_t3 tft = SSD1351_t3(CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN);
#endif

float p = 3.1415926;

void setup(void) {
  while (!Serial && millis() < 5000) ;
  Serial.begin(9600);
  Serial.print(F("Hello! SSD1351 TFT Test"));

  tft.begin();
  
  Serial.println(F("Initialized"));

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

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

  // large block of text
  tft.fillScreen(BLACK);
  testdrawtext("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. ", WHITE);
  delay(1000);

  // tft print function!
  elapsedMillis em = 0;
  tftPrintTest();
  Serial.printf("tftPrintTest: %d\n", (uint32_t)em);
  
  delay(4000);

  // a single pixel
  tft.drawPixel(tft.width()/2, tft.height()/2, GREEN);
  delay(500);

  // line draw test
  em = 0;
  testlines(YELLOW);
  Serial.printf("testlines: %d\n", (uint32_t)em);
  delay(500);

  // optimized lines
  em = 0;
  testfastlines(RED, BLUE);
  Serial.printf("testfastlines: %d\n", (uint32_t)em);
  delay(500);

  em = 0;
  testdrawrects(GREEN);
  Serial.printf("testlines: %d\n", (uint32_t)em);
  delay(500);

  em = 0;
  testfillrects(YELLOW, MAGENTA);
  Serial.printf("testlines: %d\n", (uint32_t)em);
  delay(500);

  em = 0;
  tft.fillScreen(BLACK);
  testfillcircles(10, BLUE);
  testdrawcircles(10, WHITE);
  Serial.printf("testfillcircles...: %d\n", (uint32_t)em);
  delay(500);

  em = 0;
  testroundrects();
  Serial.printf("testroundrects: %d\n", (uint32_t)em);
  delay(500);

  em = 0;
  testtriangles();
  Serial.printf("testtriangles: %d\n", (uint32_t)em);
  delay(500);

  mediabuttons();
  delay(500);

  Serial.println("done");
  delay(1000);
}

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

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);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(0, 0, tft.width()-1, y, color);
    delay(0);
  }

  tft.fillScreen(BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, 0, 0, y, color);
    delay(0);
  }

  tft.fillScreen(BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(0, tft.height()-1, x, 0, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
    delay(0);
  }

  tft.fillScreen(BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
    delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
    delay(0);
  }
}

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(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(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(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(BLACK);
  int color = 0xF800;
  int t;
  int w = tft.width()/2;
  int x = tft.height()-1;
  int y = 0;
  int z = tft.width();
  for(t = 0 ; t <= 15; t++) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x-=4;
    y+=4;
    z-=4;
    color+=100;
  }
}

void testroundrects() {
  tft.fillScreen(BLACK);
  int color = 100;
  int i;
  int t;
  for(t = 0 ; t <= 4; t+=1) {
    int x = 0;
    int y = 0;
    int w = tft.width()-2;
    int h = tft.height()-2;
    for(i = 0 ; i <= 16; 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(BLACK);
  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);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(BLACK);
  tft.setTextColor(WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(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(WHITE);
  tft.println("Sketch has been");
  tft.println("running for: ");
  tft.setTextColor(MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, GREEN);
}

So it printed out some simple elapsedMillis timings for some of the tests...

So far only testing on T4:
With my new library:
Code:
SSD1351::commandList called
SSD1351::commandList exit
Initialized
17
tftPrintTest: 1547
testlines: 233
testfastlines: 25
testlines: 24
testlines: 154
testfillcircles...: 54
testroundrects: 68
testtriangles: 35
done

Timings for Adafruit_SD1351:
Code:
Hello! SSD1351 TFT TestInitialized
40
tftPrintTest: 1602
testlines: 417
testfastlines: 58
testlines: 55
testlines: 360
testfillcircles...: 106
testroundrects: 140
testtriangles: 69
done

If I change the code to use transfer16 and I update the code that places like fillRect call to output the same color N times, to maybe build an array of up to 32 pixels and output those as one SPI.transfer(array, nullptr, cnt). I get some speed ups:
Code:
Hello! SSD1351 TFT TestInitialized
36
tftPrintTest: 1592
testlines: 396
testfastlines: 51
testlines: 49
testlines: 319
testfillcircles...: 98
testroundrects: 127
testtriangles: 64
done
But still a long way to go...

Although maybe I need to see if I can force both to use the same SPI speed and see how much of difference that maigh make
 
@KurtE

Thanks for the pointer. Did this in the 7735.h:
Code:
#ifdef __cplusplus
#include <SPI.h>
#endif

Now down to 2 errors for now - and no i didn't touch any of the DMA stuff :)

Code:
F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\ST7735_t3.h:139:3: error: unknown type name 'DMASetting'

   DMASetting      _dmasettings[2];

   ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\ST7735_t3.h:140:3: error: unknown type name 'DMAChannel'

   DMAChannel      _dmatx;

   ^
 
@KurtE

Thanks for the pointer. Did this in the 7735.h:
Code:
#ifdef __cplusplus
#include <SPI.h>
#endif

Now down to 2 errors for now - and no i didn't touch any of the DMA stuff :)

Code:
F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\ST7735_t3.h:139:3: error: unknown type name 'DMASetting'

   DMASetting      _dmasettings[2];

   ^

F:\arduino-1.8.9\hardware\teensy\avr\libraries\ST7735_t3\ST7735_t3.h:140:3: error: unknown type name 'DMAChannel'

   DMAChannel      _dmatx;

   ^

Not sure where this is going ;) As again if included from C file, then DMASettings/DMAChannel are maybe not defined... So again you could #ifdef with the __cplusplus...
arround the ST7735DMA_Data stuff..

But then the next lines are: class ST7735_t3 : public ...

Which won't work....

My guess is you are trying to bring in the ili9341_t3 like Fonts?

Two ways to fix. You could do like for example ILI9341_t3n, where you will see most of the header file including all of the classes under #ifdef __cplusplus
That is only the #defines (like colors) and the font structure are not under that #ifdef...

Or split out the font structure definition into it's own header file which both the main library header as well as the font files include that header
 
More on the Speed ups...

Actually probably good enough on T4 if you simply use higher SPI speeds...

T4 -

Code:
// Actually test now with speed set to 24mhz
My library:
[CODE]Hello! SSD1351 TFT TestSSD1351 - Hardware SPI
SSD1351::commandList called
SSD1351::commandList exit
Initialized
13
tftPrintTest: 1539
testlines: 197
testfastlines: 20
testlines: 19
testlines: 124
testfillcircles...: 45
testroundrects: 56
testtriangles: 29
done

Unmodified version:
Code:
Hello! SSD1351 TFT TestInitialized

21
tftPrintTest: 1553
testlines: 219
testfastlines: 30
testlines: 29
testlines: 186
testfillcircles...: 56
testroundrects: 73
testtriangles: 36
done

Modified version:
Code:
Hello! SSD1351 TFT TestInitialized
15
tftPrintTest: 1541
testlines: 191
testfastlines: 22
testlines: 21
testlines: 135
testfillcircles...: 45
testroundrects: 58
testtriangles: 29
done

And if you try running on T3.6. It runs OK at 15mhz and 18mhz (same speed), but display fails to display properly at 20mhz...
Code:
//// ST7735_t3 ///
T3.6 at 15mhz/18mhz
Hello! SSD1351 TFT TestSSD1351::commandList called
SSD1351::commandList exit
Initialized
18
tftPrintTest: 1548
testlines: 217
testfastlines: 27
testlines: 25
testlines: 165
testfillcircles...: 52
testroundrects: 67
testtriangles: 34
done

Fails at 20mhz

//// modified Adafruit ///
Hello! SSD1351 TFT TestInitialized
18
tftPrintTest: 1550
testlines: 248
testfastlines: 26
testlines: 25
testlines: 162
testfillcircles...: 57
testroundrects: 71
testtriangles: 37
done
 
@KurtE

Sorry Kurt thought I explained it earlier.

What I did was move/convert the primitives over from ILI9341_t3n which seemed to work in testing so far, even setOrigin and Clipping that was in ILI9341_t3n. Hey even that stuff i add about drawFloat/drawString works with the ST7735.

Now I wanted to bring over the fonts from ILI9341 and try and get it to work and that's when I ran into the issue described above. The interesting thing is that with out the font files in the directory have absolutely no compile issues with cplusplus.

I have been using the ILI9341_t3n as a guide - like we did for the ILI9488 library but guess I don't really understand about cplusplus wrappers so I messed it up. So really appreciate the guidance on this one - guess I have to do a little more reading about it.

Two ways to fix. You could do like for example ILI9341_t3n, where you will see most of the header file including all of the classes under #ifdef __cplusplus
That is only the #defines (like colors) and the font structure are not under that #ifdef...
Going to try and follow this method first before splitting it out.

EDIT: forgot I actually do have a cpluplus #ifdef around the class - so will just move it up
 
@KurtE

Just saw your post on the SSD1351 speedups. That's a nice bump for the T4 compared to the original version. Wondering about the T3.6 that its limited to 18Mhz? Maybe you need a little bit of delay like you recommended to me with the Arducam before the CS high?

Anyway fonts are now working on the ST7735 display. Looks really sharp on the 240x320 display from Adafruit. Scrolling not working right but think that's the original problem we had when I put it into the ILI9341 lib and reading the rectangle. Have to work on that one.
 
@mjs513 - I guess the real question is how fast can these actually be driven...

I probably should again put these under Logic Analyzer at the different SPI speeds...

But if I look at the SSD1351 Spec: https://www.newhavendisplay.com/app_notes/SSD1351.pdf
At Page 52 for SPI timing, I see something like:

Clock cycle min is something like: 220ns
Which looked like it did not include the fall time or rise time, which both looked like 15ns on in their charts,
So maybe something like: 250ns..

SO I would think about 4mhz? But appears to be fine at about 15. Actually with T4 it appears to work up to near 20mhz (actual SPI output speed), but was failing on T3.6 when it was running at 20mhz.
Could bee the timing differences for CS and DC. Although in Adafruit case, I am doing both in software. That is not using PUSHR to encode which CS pins are to be set/cleared...

I think one of the main speed ups might be to see why they default to something like 5mhz for Teensy?
 
@KurtE
Poking around the intenet they seem to be saying around 15 ir 18. But some folks were doing tricky things go get faster. Assembly and registers on arduino. So don't know how much faster your going to able to go with just doing transfers.
 
The interesting thing about trying to update the underlying library (SPITFT) will be seeing how each of the display types can (or not) set their default SPI speeds. Obviously different controllers probably have different max speeds.

One thing I would like to do is to update all of the ones that I play with hopefully have something like this on their begin/init/??? function that sets the specific desired speed for that program.

I can imagine this could be important for some setups as maybe they use longer wires or ...


Also @Paul - I wish I could have put in the function: SPI.transfer16(buffer, retbuf, cnt), or maybe the ESP32 version writePixel(), as with a lot of these drivers things would be a lot easier and with less overhead:

Example in SPITFT:
Code:
void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len,
  bool block, bool bigEndian) {

    if(!len) return; // Avoid 0-byte transfers

#if defined(ESP32) // ESP32 has a special SPI pixel-writing function...
    if(connection == TFT_HARD_SPI) {
        hwspi._spi->writePixels(colors, len * 2);
        return;
    }
#elif defined(USE_SPI_DMA)
... 
#else 
    // All other cases (bitbang SPI or non-DMA hard SPI or parallel),
    // use a loop with the normal 16-bit data write function:
    while(len--) {
        SPI_WRITE16(*colors++);
    }
So this one, unless I go down to the registers level I am left with two possibilities...
a) Leave as it is, which transfers, which translates into:
while(len--)SPI.transfer16(*colors++);
Which will not keep anything in FIFO queue.

b) Use temporary buffer to copy a portion of the output into and then call block transfer (which I may try next)
Something like:
Code:
#elif defined(KINETISK) || defined(KINETISL) || defined(__IMXRT1062__)
    if(connection == TFT_HARD_SPI) {
        #define SPI_MAX_WRITE_PIXELS_AT_ONCE 32
        static uint8_t temp[SPI_MAX_WRITE_PIXELS_AT_ONCE*2];
        uint8_t *pb = temp;
        while (len) {
          *pb++ = *colors >> 8;
          *pb++ = *colors++ &0xff;
          if (pb == &temp[SPI_MAX_WRITE_PIXELS_AT_ONCE*2]) {
            hwspi._spi->transfer((uint8_t *)temp, nullptr, SPI_MAX_WRITE_PIXELS_AT_ONCE*2);
            pb = temp;
          }
          len--;
        }
        // if there is anything remaing in buffer output it now
        if (pb != &temp[0]) {
            hwspi._spi->transfer((uint8_t *)temp, nullptr, (uint32_t)pb-(uint32_t)&temp[0]);          
        }
        return;
    }
 
@KurtE

Would think the block transfers would be better for the teensies, I would think if you are going to incorporate it into the Adafruit library.

Its interesting poking around GitHub. While trying to get readrect working for the ST7789 came across the library by Bodmer which is rather interesting. He seems to have got it working by the way. But that's besides the point. What I was going to say was that he has SPI clock at 40Mhz and SPI read at 6Mhz (max).

Unfortunately he doesn't support the ssd1351 so no help on the settings for that one.

I'll post another question on the readrect.
 
Back
Top