ILI9488_t3 - Support for the ILI9488 on T3.x and beyond...

@KurtE - I know the feeling - once you start something you don't want to stop until it works :)

@defragster - I just made up a board yesterday and ordered them to test tri-state to see if it works. Probably won't get them until the end of the week to test.
Capture1.JPG

If you want one to play with I send a couple when I get them - @KurtE if you want I can send a couple to you as well.
 
@KurtE - I know the feeling - once you start something you don't want to stop until it works :)
Hi Mike, yep sometimes you just want to get it working!

I remember the T3.5 being a pain in the A... with DMA and SPI... Wish I remember all of the details.
I did put a few comments in the ILI9341_t3n code about the scatter/gather stuff of DMA not working properly... I ran into this first in the SPI library when I was trying to get the Async SPI.transfer to work... I also remember that SPI1/SPI2 were a real pain as they only give one DMA trigger event for SPI1 and SPI2 and that they could be used for either TX or RX (but not both)... So ended up with code where a dummy RX transfer drove it...

And then when I added support for frame buffer to T3.5, I don't remember if maybe on SPI0 if I could get away with only the TX transfer running... So I more or less simply emulated the SPI library... Not sure how much time I want to use here to experiment to see...

I might try a quick and dirty update...

And back to comment about updating ILI9341_t3n to not need SPIN... Yes could do it, using same hacks I am using here... For the first part... Actaully wish we would just export some of the data in SPI library such that we don't have to hack!

The only other thing that the SPIN gave me, was it had several of the standard functions we keep copying from one library to another. like:
waitTransmitComplete, waitFifoNotFull... But as mentioned other option is to simply copy the code.

EDIT: As for the buffer board. Probably don't need yet as I don't have the same display (yet)
 
Hi Mike, yep sometimes you just want to get it working!

I remember the T3.5 being a pain in the A... with DMA and SPI... Wish I remember all of the details.
I did put a few comments in the ILI9341_t3n code about the scatter/gather stuff of DMA not working properly... I ran into this first in the SPI library when I was trying to get the Async SPI.transfer to work... I also remember that SPI1/SPI2 were a real pain as they only give one DMA trigger event for SPI1 and SPI2 and that they could be used for either TX or RX (but not both)... So ended up with code where a dummy RX transfer drove it...

And then when I added support for frame buffer to T3.5, I don't remember if maybe on SPI0 if I could get away with only the TX transfer running... So I more or less simply emulated the SPI library... Not sure how much time I want to use here to experiment to see...

I might try a quick and dirty update...
If it were me if I definitely wouldn't bother with SPI1/2 if its that much of an issue and would concentrate on SPI0. If not, would worry about supporting frame buffer on the T3.5 if its that much of an issue.

And back to comment about updating ILI9341_t3n to not need SPIN... Yes could do it, using same hacks I am using here... For the first part... Actaully wish we would just export some of the data in SPI library such that we don't have to hack!

The only other thing that the SPIN gave me, was it had several of the standard functions we keep copying from one library to another. like:
waitTransmitComplete, waitFifoNotFull... But as mentioned other option is to simply copy the code.[/QOUTE] Me too but copy paste always work.
Talking out of my hat here, was reading something about friend classes once couldn't you do something like that to get access to the functions?

EDIT: As for the buffer board. Probably don't need yet as I don't have the same display (yet)
Let me know and i will send a couple. Going to try it first and let you all know if it works.
 
Given the amount of data to be transferred for 9488 - doing it with more overhead and smaller FIFO will slow it down. Certainly for first pass SPI0 being done well seems most important - especially if anyone gets a T$1062.

@mjs513 - the p#126 TriState looks interesting. Depending on connect ability path I could use at least one for breadboard - not sure how it would adapt to Teensy36 connect? Did you order enough of the chips to include?

Would be nice to have an updated PJRC OSH Purple display board with that feature.

As noted I got 8 of the 8MB RAM chips and could share a pair your way - Frank sent some code for his Flash adapters. I have not soldered any up yet - also assuming they should mount on Audio SPI chip spot - and I have a Prop Shield the AMP failed on - so could pull off that 8 MB Flash and replace with a RAM for test.

Having FULL FIFO DMA RAM could make it easier to think of a way to use it :)
 
@defragster - yep. Have about 12 of them on hand so I can include them with the boards. Just shoot me an email with your address. Probably won't have the boards until early next week though. Thanks for the offer on the 8MB chips - I actually ordered a bunch just in case. Not sure how to use them yet though. The data sheet is rather sparse.
 
@mjs513/defragster...

Sometimes I would like to take one of these boards/display and run over it :mad: :lol:

I made some changes to try to support T3.5, but finding something is screwing up something...

That is, one of the display programs will not display anything now on the T3.5... I understand if maybe I am calling something that is screwed up...

That is I have the modified version of the app, I was using to test some frame buffer and Async support:
Code:
//=============================================================================
//=============================================================================
#include <ILI9488_t3.h>
#include <ILI9488_t3_font_Arial.h>
#include <ILI9488_t3_font_ArialBold.h>
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
ILI9488_t3 tft = ILI9488_t3(&SPI, TFT_CS, TFT_DC, TFT_RST);

uint16_t our_pallet[] = {
  ILI9488_BLACK,  ILI9488_RED, ILI9488_GREEN,  ILI9488_BLUE,   ILI9488_WHITE,
  ILI9488_YELLOW, ILI9488_ORANGE, ILI9488_CYAN, ILI9488_PINK
};

//=============================================================================
// Setup
//=============================================================================
void setup()
{
  tft.begin();
  tft.setRotation(3); // 180
  delay(100);
  tft.fillScreen(ILI9488_BLACK);
  delay(250);
  tft.fillScreen(ILI9488_RED);
  delay(250);
  tft.fillScreen(ILI9488_BLUE);
  delay(250);
  tft.fillScreen(ILI9488_GREEN);
  delay(250);
  tft.fillScreen(ILI9488_BLACK);
  while (!Serial && millis() < 4000) ;
  Serial.begin(115200);
  delay(50);
  Serial.println("Test ILI9488 frame buffer");

  tft.fillScreen(ILI9488_BLACK);
  tft.useFrameBuffer(true);
  tft.setPallet(our_pallet, sizeof(our_pallet) / sizeof(our_pallet[0]));  tft.colorsArePalletIndex(true);
  delay(250);
}
//=============================================================================
// Loop
//=============================================================================
int zz = 0;
uint32_t non_frame_buffer_time[2] = {0, 0};
uint32_t frame_buffer_time[2] = {0, 0};
void loop()
{
  // First simple pallet output sync output
  tft.fillScreen(0);
  uint16_t x = 5;
  uint16_t y = 5;

  for (uint8_t i = 1; i < (sizeof(our_pallet) / sizeof(our_pallet[0])); i++) {
    tft.drawRect(x, y, tft.width() - x * 2, tft.height() - y * 2, i);
    x += tft.width() / 16;
    y += tft.height() / 16;
  }
  tft.updateScreen();
  delay(2500);

  x = 5;
  y = 5;

  // next simple pallet Async output;
  for (uint8_t i = 1; i < (sizeof(our_pallet) / sizeof(our_pallet[0])); i++) {
    tft.fillRect(x, y, tft.width() - x * 2, tft.height() - y * 2, i);
    x += tft.width() / 16;
    y += tft.height() / 16;
  }
//#if 1
 [COLOR="#FF0000"] //tft.updateScreen();
//#else
  tft.updateScreenAsync();  // Try an async update...[/COLOR]
#if 0
  tft.waitUpdateAsyncComplete();
  delay(2500);

  // Next lets try some continuous outputs...
  // Lets update the screen in 16 chunks, every 2 frames.
  uint32_t next_update_frame_count = 2;
  tft.setTextColor(0);
  tft.setTextSize(2);
  tft.setCursor(5, 5);
  tft.print("Cont...");
  tft.updateScreen();
  tft.updateScreenAsync(true);  // Try an async update...
  for (uint16_t i = 1; i <= 16; i++) {
    // wait for the next frame...
    while (tft.frameCount() < next_update_frame_count) ;
    x = 5;
    y = 5;
    tft.setClipRect(1, 1, tft.width()-2, i * (tft.height() / 16) -2);
    for (uint8_t i = 1; i < (sizeof(our_pallet) / sizeof(our_pallet[0])); i++) {
      tft.fillRect(x, y, tft.width() - x * 2, tft.height() - y * 2, 8 - i);
      x += tft.width() / 16;
      y += tft.height() / 16;
    }
    next_update_frame_count += 2;
  }
  tft.setClipRect();
  tft.endUpdateAsync();  // Tell system to cancel async updates
  tft.waitUpdateAsyncComplete();
/*
  delay(1000);
  for (uint16_t kk = 0; kk < 8; kk++) {
    for (uint16_t jj = 1; jj < sizeof(our_pallet) / sizeof(our_pallet[0]); jj++) {
      for (uint16_t i = 1; i <= 16; i++) {
        x = 5;
        y = 5;
        tft.setClipRect(0, 0, tft.width(), i * (tft.height() / 16));
        for (uint8_t i = 1; i < (sizeof(our_pallet) / sizeof(our_pallet[0])); i++) {
          if ( kk < 4 )
            tft.fillRect(x, y, tft.width() - x * 2, tft.height() - y * 2, ((jj + i) % 9));
          else
            tft.fillRect(x, y, tft.width() - x * 2, tft.height() - y * 2, ((18 + (jj - i)) % 9));
          x += tft.width() / 16;
          y += tft.height() / 16;
        }
      }
      tft.updateScreen();
      tft.waitUpdateAsyncComplete();
    }
  }
*/  
  delay(1000);
  tft.fillScreen(0);  // Turn all read;
  tft.drawRect(0, 0, tft.width()-1, tft.height()-1, 1);
  tft.drawLine(0, 0, tft.width(), tft.height(), 2);
  tft.drawLine(0, tft.height()-1, tft.width()-1, 0, 2);
  tft.updateScreen();
  delay(500);
  tft.updateScreenAsync();
  tft.waitUpdateAsyncComplete();
#endif
  delay(1000); 
}
That is if the lines in Red, if I only call updateScreen, the program runs. If however I put in as it is:
updateScreenAsync, the program runs, but nothing shows up on the screen... I understand that there could be bugs and that part of the code might completely screw up, but with that line in there, nothing shows up on the display (goes white), does not show the screen changing several colors at the start... ???

The code runs, as I have some debug outputs, like the async functions are getting called...
Code:
Test ILI9488 frame buffer
updateScreenAsync called
After initDMASettings called
After setAddr called
Just before _dmatx.enable called
updateScreenAsync called
After initDMASettings called
After setAddr called
Just before _dmatx.enable called
 
@KurtE and @defragster
Just updated post 1 and the readme in the master. Feel free to change to your hearts content.

@KurtE - know this is going to sound funny but are you sure you are pointing to the right SPI bus in updateScreenAsync? As you know I forgot a whole bunch of times to change/update lines that loused me up. You been at it so long you eyes have to be crossed by now.
 
@mjs513 - sent email with address for TriState board(s). Also in that was the code FrankB sent that he saw working on a prior board of his.

Remember the sketch I did that showed there was no actual Buffering in place? My github is pretty current - but not current MASTER.

On T$ this is not showing as expected. The BLACK screen is NO BUFF and it draws in parts.

Then the background goes BLUE and the BLUE section is set to BLACK so it has contrast ...

Then it does the rest and The BUFFER version shows up in BLACK? - Like it has recalled the prior UNBUFFERED code?

Not sure if this is my failure to do something?
Code:
//=============================================================================
//=============================================================================

#include <ILI9488_t3.h>
#include <ILI9488_t3_font_Arial.h>
#include <ILI9488_t3_font_ArialBold.h>


#ifdef __MK66FX1M0__
#define __C64__ 1
#else
#endif

// Connection konfiguration of ILI9341 LCD TFT
#if defined(__C64__)
#define SCK       14
#define MISO      39
#define MOSI      28
#define TFT_RST 255
#define TFT_DC 20
#define TFT_CS 21
ILI9488_t3 tft = ILI9488_t3(TFT_CS, TFT_DC, TFT_RST, MOSI, SCK, MISO );
#else
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
ILI9488_t3 tft = ILI9488_t3(TFT_CS, TFT_DC, TFT_RST);
#endif
//=============================================================================
// Setup
//=============================================================================
boolean use_frame_buffer = true;
void setup()
{
	tft.begin();
	tft.setRotation(3); // 180
	delay(100);

	tft.fillScreen(ILI9488_BLACK);
	delay(250);
	tft.fillScreen(ILI9488_RED);
	delay(250);
	tft.fillScreen(ILI9488_BLUE);
	delay(250);
	tft.fillScreen(ILI9488_GREEN);
	delay(250);
	tft.fillScreen(ILI9488_BLACK);
	tft.useFrameBuffer(use_frame_buffer);
	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
}

int ii = 0;
void drawColor(uint16_t x, uint16_t y, const char *psz, uint16_t color)
{
	static uint16_t cLast = ILI9488_WHITE;
	tft.setFontAdafruit();
	tft.setTextColor(color);
	tft.setTextSize(2);
	tft.setCursor(x, y);
	if ( 0 == ii % 10 ) tft.print(psz);
	if ( 1 == ii % 10 ) tft.drawRect(x + 100, y, 50, 50, color);
	if ( 2 == ii % 10 ) tft.fillRect(x + 110, y + 10, 30, 5, cLast);
	if ( 7 == ii % 10 ) tft.drawLine(x + 100, y + 70, x + 200, y + 70, color);
	if ( 4 == ii % 10 ) tft.drawLine(x + 220, y, x + 220, y + 70, color);
	if ( 5 == ii % 10 ) tft.drawLine(x + 100, y + 70, x + 220, y, color);
	if ( 6 == ii % 10 ) tft.drawCircle(x + 50, y + 50, 28, color);
	if ( 3 == ii % 10 ) tft.fillCircle(x + 50, y + 50, 5, cLast);
	tft.setFont(Arial_12_Bold);
	tft.setCursor(x + 160, y + 50);
	if ( 8 == ii % 10 ) tft.print(psz);
	if ( 9 == ii % 10 ) tft.fillCircle(x + 50, y + 50, 20, color);
	if ( 9 == ii % 10 ) tft.fillRect(x + 110, y + 10, 30, 30, color);
	cLast = color;
}


//=============================================================================
// Loop
//=============================================================================
void loop()
{
	tft.setFont(Arial_18_Bold);
	tft.setCursor(0, 150);
	if ( 0 == (ii % 10) ) {
		if (!use_frame_buffer) {
			tft.fillScreen(ILI9488_BLUE);
		} else {
			tft.fillScreen(ILI9488_BLACK);
		}
	}
	drawColor(0, 0, "Red", ILI9488_RED);
	drawColor(0, 80, "Green", ILI9488_GREEN);
		drawColor(0, 240, "White", ILI9488_WHITE);
	if ( use_frame_buffer ) {
		drawColor(0, 160, "Blue", ILI9488_BLUE);
	}
	else {
		drawColor(0, 160, "Black", ILI9488_BLACK);
	}

	drawColor(240, 0, "Yellow", ILI9488_YELLOW);
	drawColor(240, 80, "Orange", ILI9488_ORANGE);
	drawColor(240, 160, "Cyan", ILI9488_CYAN);
	drawColor(240, 240, "Pink", ILI9488_PINK);
	if ( !use_frame_buffer )
		delay(20);
	if ( !(ii % 10) ) {
		if (use_frame_buffer) {
			tft.updateScreen();
			use_frame_buffer = false;
		} else {
			use_frame_buffer = true;
		}
		tft.useFrameBuffer(use_frame_buffer);
		delay(1500);
	}
	else if ( 9 == (ii % 10) && use_frame_buffer) {
		tft.updateScreen();
		delay(1500);
	}
	ii++;
}
 
@mjs513 - I am looking for funny sounding suggestions, as some of the more obvious things have not panned out...

But as I said I would understand it (IF I actually called the code)...
Again a simplified version:
Code:
#include <ILI9488_t3.h>
#include <ILI9488_t3_font_Arial.h>
#include <ILI9488_t3_font_ArialBold.h>
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
ILI9488_t3 tft = ILI9488_t3(&SPI, TFT_CS, TFT_DC, TFT_RST);

uint16_t our_pallet[] = {
  ILI9488_BLACK,  ILI9488_RED, ILI9488_GREEN,  ILI9488_BLUE,   ILI9488_WHITE,
  ILI9488_YELLOW, ILI9488_ORANGE, ILI9488_CYAN, ILI9488_PINK
};

//=============================================================================
// Setup
//=============================================================================
void setup()
{
  while (!Serial && millis() < 4000) ;
  Serial.begin(115200);
  delay(50);
  Serial.println("Test ILI9488 frame buffer");

  tft.begin();
  tft.setRotation(3); // 180
  delay(100);
  tft.fillScreen(ILI9488_BLACK);
  delay(250);
  tft.fillScreen(ILI9488_RED);
  delay(250);
  tft.fillScreen(ILI9488_BLUE);
  delay(250);
  tft.fillScreen(ILI9488_GREEN);
  delay(250);
  tft.fillScreen(ILI9488_BLACK);

  tft.fillScreen(ILI9488_BLACK);
  tft.useFrameBuffer(true);
  tft.setPallet(our_pallet, sizeof(our_pallet) / sizeof(our_pallet[0]));  
  tft.colorsArePalletIndex(true);
  delay(250);
}
//=============================================================================
// Loop
//=============================================================================
int zz = 0;
uint32_t non_frame_buffer_time[2] = {0, 0};
uint32_t frame_buffer_time[2] = {0, 0};
void loop()
{
  // First simple pallet output sync output
  tft.fillScreen(0);
  uint16_t x = 5;
  uint16_t y = 5;

  for (uint8_t i = 1; i < (sizeof(our_pallet) / sizeof(our_pallet[0])); i++) {
    tft.drawRect(x, y, tft.width() - x * 2, tft.height() - y * 2, i);
    x += tft.width() / 16;
    y += tft.height() / 16;
  }
  tft.updateScreen();
  delay(2500);
#if 0
  tft.updateScreenAsync();  // Try an async update...
  tft.waitUpdateAsyncComplete();
#endif
  delay(2500);
}
if you change the #if 0 to #if 1 the fillScreens at the start of the program don't work... Even if it can never get called, like if I change the #if 0 block to:
Code:
#if 1
  if (zz != 0) {
    tft.updateScreenAsync();  // Try an async update...
    tft.waitUpdateAsyncComplete();
  }
#endif
So I am thinking it is maybe bringing in some of the other objects associated with DMA, which is maybe screwing up the memory... Still debugging

EDIT: Note: if you change the code above like I mentioned where it should not be called, but updateScreenAsync() is compiled in, the program data usage grows by about 384 (compiled)... At least in debug mode, now going back to default compile options (faster) -- Same sizes for Faster (5584 versus 5968)
 
Last edited:
@KurtE
Sorry - been away from the computer today - are these the changes you pushed to the master or in your WIP. Want to give it a try but not sure I have the latest version that you are working with?

EDIT: Don't think I have your latest - the version I have gives me compile errors for the T3.5
 
Last edited:
@mjs513 - I have been away a lot today as well. Just got back... Annie turned 6 months old last week and today had THE surgery... Just picked her up from Vet...

I got it working more putting in a Serial.printf() at the start of the begin method... Probably some timing issue...

Pushed up new WIP branch (T35_WIP)
 
RE- POST #133 - more later - but I just saw my logic is backwards on the fillscreen - so it is the non-FB that is being odd ...
 
@KurtE

Just updated and ran your sketch on the T3.5 it did run with the, if 1, set. This is what the sermon is showing for the first update:
Code:
Test ILI9488 frame buffer
::begin 1fff0710 4002c000 a6ec 11 12 13
updateScreenAsync called
After initDMASettings called
dumpDMASettings called
1fff1434 40009000:SA:1fff1247 SO:1 AT:0 NB:1 SL:-237 DA:4002c034 DO: 0 CI:ed DL:0 CS:a BI:ed
After setAddr called
Just before _dmatx.enable called
But I am not seeing a serial.printf in begin()? I even turned of async debug
 
@KurtE and @defragster

Tried with a couple of other sketches:
1. Buddhabrot works - no FB/DMA
2. Scroll test - fails all around, no FB/DMA, FB no async, FB w/palette or with Palette. Didn't even bother to try async
 
@mjs513/@defragster - I think I fixed the strange issue of not starting sometimes and sometimes yes...

The problem was in the init_commands table In particular the 2nd line at least had the byte 0xE1 missing, which caused the length field to be wrong and so the init code might walk off the end of table and results depended on what was there...

So I went back through table and made it be the same Init values as I think the other ILI9488 library is using...

So test cases running... DMA has issues T3.5, but that was what I started off trying to see what it is doing...

Pushed up current changes for table... Have not tried it on other processors yet.
 
Still stuck understanding how to get the SWAP{ no_FB, yes_FB }

That was in the initial sample - where delay()'s showed it needed work it got!

But there is some failure - in the 'user' code here - or in the underlying library?

Rather than jumping in place in LOOP() I've split those out to separate loop#'s doing either one or the other trying to remove the crosstalk. As presented below it opens - runs 5 passes w/no_FB then jumps to yes_FB - seems to work ... then it tried to restart to the no_FB and there is crosstalk.

Sorry this desperation resulted in much more code - but as presented jumping loop3() then loop4() should be easy enough to ignore the initial dormant code in loop() - and loop2&3 were meant to jump to one another alternating - but that was failing ... thus #3

You can see &SPI - this is the now current :: KurtE/ILI9488_t3/tree/T35_WIP

Same behavior shows - first Jump to FB shows ORANGE - that clears, then on return to no_FB it keeps using the FB BUFFER page where FB___ YES shows on BLUE ??? :::
Code:
//=============================================================================
//=============================================================================

#include <ILI9488_t3.h>
#include <ILI9488_t3_font_Arial.h>
#include <ILI9488_t3_font_ArialBold.h>


#ifdef __MK66FX1M0__
#define __C64__ 1
#else
#endif

// Connection konfiguration of ILI9341 LCD TFT
#if defined(__C64__)
#define SCK       14
#define MISO      39
#define MOSI      28
#define TFT_RST 255
#define TFT_DC 20
#define TFT_CS 21
ILI9488_t3 tft = ILI9488_t3( &SPI, TFT_CS, TFT_DC, TFT_RST, MOSI, SCK, MISO );
#else
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
ILI9488_t3 tft = ILI9488_t3( &SPI, TFT_CS, TFT_DC, TFT_RST);
#endif
//=============================================================================
// Setup
//=============================================================================
boolean use_frame_buffer = true;
void setup()
{
	tft.begin();
	tft.setRotation(3); // 180
	delay(100);

	tft.fillScreen(ILI9488_BLACK);
	delay(250);
	tft.fillScreen(ILI9488_RED);
	delay(250);
	tft.fillScreen(ILI9488_BLUE);
	delay(250);
	tft.fillScreen(ILI9488_GREEN);
	delay(250);
	tft.fillScreen(ILI9488_BLACK);
	tft.useFrameBuffer(use_frame_buffer);
	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
}

int ii = 0;
void drawColor(uint16_t x, uint16_t y, const char *psz, uint16_t color)
{
	static uint16_t cLast = ILI9488_WHITE;
	tft.setFontAdafruit();
	tft.setTextColor(color);
	tft.setTextSize(2);
	tft.setCursor(x, y);
	if ( 0 == ii % 10 ) tft.print(psz);
	if ( 1 == ii % 10 ) tft.drawRect(x + 100, y, 50, 50, color);
	if ( 2 == ii % 10 ) tft.fillRect(x + 110, y + 10, 30, 5, cLast);
	if ( 7 == ii % 10 ) tft.drawLine(x + 100, y + 70, x + 200, y + 70, color);
	if ( 4 == ii % 10 ) tft.drawLine(x + 220, y, x + 220, y + 70, color);
	if ( 5 == ii % 10 ) tft.drawLine(x + 100, y + 70, x + 220, y, color);
	if ( 6 == ii % 10 ) tft.drawCircle(x + 50, y + 50, 28, color);
	if ( 3 == ii % 10 ) tft.fillCircle(x + 50, y + 50, 5, cLast);
	tft.setFont(Arial_12_Bold);
	tft.setCursor(x + 160, y + 50);
	if ( 8 == ii % 10 ) tft.print(psz);
	if ( 9 == ii % 10 ) tft.fillCircle(x + 50, y + 50, 20, color);
	if ( 9 == ii % 10 ) tft.fillRect(x + 110, y + 10, 30, 30, color);
	cLast = color;
}


//=============================================================================
// Loop
//=============================================================================
void loop()
{
	static int ONLY_NO_FB = 1;
	static int yy = 0;

	if ( 1 == ONLY_NO_FB ) {
		loop3(); // NOT FB
		yy++;
		if ( yy > 50 ) {
			delay( 700 );
			ONLY_NO_FB = 4;
			tft.useFrameBuffer(true);
		}
		return;
	}
	if ( 4 == ONLY_NO_FB ) {
		loop4(); // ONLY FB
		yy++;
		if ( yy > 100 ) {
			delay( 700 );
			ONLY_NO_FB = 1;
			tft.useFrameBuffer(false);
		}
		return;
	}


	if ( 2 == ONLY_NO_FB ) { // alternate
		if ( use_frame_buffer ) loop1();
		else loop2();
		return;
	}

// ORIGINAL EFFORT TO ALTERNATE

	tft.setFont(Arial_18_Bold);
	tft.setCursor(0, 150);
	if ( 0 == (ii % 10) ) {
		if (use_frame_buffer) {
			tft.fillScreen(ILI9488_BLUE);
			tft.print("-- FB _+_ YES L");
		} else {
			tft.fillScreen(ILI9488_BLACK);
			tft.print("__ FB _-_ NOT L");
		}
	}
	drawColor(0, 0, "Red", ILI9488_RED);
	drawColor(0, 80, "Green", ILI9488_GREEN);
	drawColor(0, 240, "White", ILI9488_WHITE);
	if ( use_frame_buffer ) {
		drawColor(0, 160, "Blue", ILI9488_BLUE);
	}
	else {
		drawColor(0, 160, "Black", ILI9488_BLACK);
	}

	drawColor(240, 0, "Yellow", ILI9488_YELLOW);
	drawColor(240, 80, "Orange", ILI9488_ORANGE);
	drawColor(240, 160, "Cyan", ILI9488_CYAN);
	drawColor(240, 240, "Pink", ILI9488_PINK);
	if ( !use_frame_buffer )
		delay(50);
	if ( !(ii % 10) ) {
		if (use_frame_buffer) {
			tft.updateScreen();
			use_frame_buffer = false;
		} else {
			use_frame_buffer = true;
		}
		tft.useFrameBuffer(use_frame_buffer);
		delay(1500);
		tft.updateScreen();
	}
	else if ( 9 == (ii % 10) && use_frame_buffer) {
		tft.updateScreen();
		delay(1500);
	}
	ii++;
}

void loop1() //	if ( use_frame_buffer ) loop1();
{
	tft.setFont(Arial_18_Bold);
	tft.setCursor(0, 150);
	if ( 0 == (ii % 10) ) {
		tft.fillScreen(ILI9488_BLUE);
		tft.print("-- FB _+_ YES 1");
	}
	drawColor(0, 0, "Red", ILI9488_RED);
	drawColor(0, 80, "Green", ILI9488_GREEN);
	drawColor(0, 240, "White", ILI9488_WHITE);

	drawColor(0, 160, "Black", ILI9488_BLACK);

	drawColor(240, 0, "Yellow", ILI9488_YELLOW);
	drawColor(240, 80, "Orange", ILI9488_ORANGE);
	drawColor(240, 160, "Cyan", ILI9488_CYAN);
	drawColor(240, 240, "Pink", ILI9488_PINK);
	if ( !(ii % 10) ) {
		tft.updateScreen();
		use_frame_buffer = false;
		tft.useFrameBuffer(use_frame_buffer);
		delay(1500);
		tft.updateScreen();
	}
	else if ( 9 == (ii % 10) ) {
		tft.updateScreen();
		delay(1500);
	}
	ii++;
}

void loop2() //	else loop2(); // !use_frame_buffer
{
	tft.setFont(Arial_18_Bold);
	tft.setCursor(0, 150);
	if ( 0 == (ii % 10) ) {
		tft.fillScreen(ILI9488_BLACK);
		tft.print("__ FB _-_ NOT 2");
	}
	drawColor(0, 0, "Red", ILI9488_RED);
	drawColor(0, 80, "Green", ILI9488_GREEN);
	drawColor(0, 240, "White", ILI9488_WHITE);

	drawColor(0, 160, "Blue", ILI9488_BLUE);

	drawColor(240, 0, "Yellow", ILI9488_YELLOW);
	drawColor(240, 80, "Orange", ILI9488_ORANGE);
	drawColor(240, 160, "Cyan", ILI9488_CYAN);
	drawColor(240, 240, "Pink", ILI9488_PINK);
	delay(50);
	if ( !(ii % 10) ) {
		use_frame_buffer = true;
		tft.useFrameBuffer(use_frame_buffer);
		delay(1500);
		tft.updateScreen();
	}
	ii++;
}

void loop3() //	else loop2(); // !use_frame_buffer
{
	use_frame_buffer = false;
	tft.useFrameBuffer(use_frame_buffer);
	tft.setFont(Arial_18_Bold);
	tft.setCursor(0, 150);
	if ( 0 == (ii % 10) ) {
		tft.fillScreen(ILI9488_BLACK);
		tft.print("__ FB _-_ NOT 3");
	}
	drawColor(0, 0, "Red", ILI9488_RED);
	drawColor(0, 80, "Green", ILI9488_GREEN);
	drawColor(0, 240, "White", ILI9488_WHITE);

	drawColor(0, 160, "Blue", ILI9488_BLUE);

	drawColor(240, 0, "Yellow", ILI9488_YELLOW);
	drawColor(240, 80, "Orange", ILI9488_ORANGE);
	drawColor(240, 160, "Cyan", ILI9488_CYAN);
	drawColor(240, 240, "Pink", ILI9488_PINK);
	delay(50);
	if ( !(ii % 10) ) {
		delay(1500);
	}
	ii++;
}

void loop4() //	if ( use_frame_buffer ) loop1();
{
	tft.setFont(Arial_18_Bold);
	tft.setCursor(0, 150);
	if ( 0 == (ii % 10) ) {
		tft.fillScreen(ILI9488_BLUE);
		tft.print("-- FB _+_ YES 4");
	}
	drawColor(0, 0, "Red", ILI9488_RED);
	drawColor(0, 80, "Green", ILI9488_GREEN);
	drawColor(0, 240, "White", ILI9488_WHITE);

	drawColor(0, 160, "Black", ILI9488_BLACK);

	drawColor(240, 0, "Yellow", ILI9488_YELLOW);
	drawColor(240, 80, "Orange", ILI9488_ORANGE);
	drawColor(240, 160, "Cyan", ILI9488_CYAN);
	drawColor(240, 240, "Pink", ILI9488_PINK);
	if ( !(ii % 10) ) {
		tft.updateScreen();
		delay(1500);
	}
	else if ( 9 == (ii % 10) ) {
		tft.updateScreen();
		delay(1500);
	}
	ii++;
}
>> Just updated code again - add '+' or '-' to the FB __ printing and it shows the LOOP# after YES or NO so you can see what code should be doing the display.

Why does the no_FB slowly draw on the yes_FB blue page with the word YES on it?????
 
Last edited:
@KurtE and @defragster

Can't believe I messed that table up. Thought I had checked it - guess not good enough. Yes the intention was to make the two tables match.

I just tried my scolltest.ino sketch again. It only works correctly when FB is enabled, otherwise, only the last line is updated when it reaches the end.
 
@KurtE and @defragster

If you all want to laugh. The 9488 library seems to work fine on a 9341 display as well as long as you remember to change the screen resolution in the .h file. It was one of those things that I had to try.
 
@mjs513 @defragster

Good to hear the two display chips are so similar, which probably makes some sense as to mainly update to chip for larger display... But I am sort of surprised the 24 bit color output works without many changes.... (On the init table, I thought I checked them as well earlier... I maybe screwed it up at some point.

Sounds like the scroll test failed with out FB as readPixel/readRect probably failed...

For sure it needs changes for SPI1/SPI2 code, with lines like: if (txCount && ((_pkinetisk_spi->SR & 0xF000) >> 12) < 4) {

T3.5 and DMA: (currently a bit distracted) Made some progress yesterday, looks like the DMA chunks are maybe being generated, but the CS pin is not held as active... So the high word of PUSHR register is being updated at some point so it does not remember... Maybe would work if CS was not hardware CS pin, but...

Also I know I/we need to update the ::begin() method to properly handle Serial1/Serial2 and cleanup...
That is is starts with:
Code:
    #ifdef KINETISK
    #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
    // Allow to work with mimimum of MOSI and SCK
    if ((_mosi == 255 || _mosi == 11 || _mosi == 7 || _mosi == 28)  && (_sclk == 255 || _sclk == 13 || _sclk == 14 || _sclk == 27)) 
	#else
    if ((_mosi == 255 || _mosi == 11 || _mosi == 7) && (_sclk == 255 || _sclk == 13 || _sclk == 14)) 
    #endif	
    {
Nice thing these days is we should NOT be looking at the pins directly here to know if proper pins...
That is if we wish to know if pin _mosi is valid for SPI0 We should do: if ((_mosi == 255) || spi_port->pinISMOSI(_mosi))

So it handles properly which port and uses SPI tables/code to decide if valid... And of course could do what I did in ILI9341_t3n, that goes:
mosi, miso, sclk are defined but not valid on the specified SPI port. Is there a port they are valid on? If so Update to use the proper SPI Port...

@defragster - I need to go back and reread your questions, I have been sort of tunnel visioned on trying to remember the T3.5...

Now back to distractions and seeing if I remember how the CS pin was handled on 9341... And or do I need to go down the rabbit hole for 3.5 where I had to enable two DMA transfers (RX and TX) where RX drove the TX...
 
@KurtE @defragster
For sure it needs changes for SPI1/SPI2 code, with lines like: if (txCount && ((_pkinetisk_spi->SR & 0xF000) >> 12) < 4) {
You got me here - have to go look at the code and SPI.

T3.5 and DMA: (currently a bit distracted) Made some progress yesterday, looks like the DMA chunks are maybe being generated, but the CS pin is not held as active... So the high word of PUSHR register is being updated at some point so it does not remember... Maybe would work if CS was not hardware CS pin, but...
I know this is going to sound funny, and maybe not pertinent but when I was trying to figure the touch issue I saw someplace where someone added a small delay before the CS was made to go LOW. Would that work here?

Nice thing these days is we should NOT be looking at the pins directly here to know if proper pins...
That is if we wish to know if pin _mosi is valid for SPI0 We should do: if ((_mosi == 255) || spi_port->pinISMOSI(_mosi))

So it handles properly which port and uses SPI tables/code to decide if valid... And of course could do what I did in ILI9341_t3n, that goes:
mosi, miso, sclk are defined but not valid on the specified SPI port. Is there a port they are valid on? If so Update to use the proper SPI Port...
I'll take a look at that if you would like. But it will probably be later than sooner - have a some doctors appointments etc today.

Good luck with the rabbit hole.

BTW> When my little one had her surgery we had to watch her like a hawk so she wouldn't be jumping all over the place the next day. :)
 
@KurtE, @defragster

Ok before I start the day have a couple of questions. Updating to what you have in your SPIN class doesn't look hard but I do have a question in conversion to the 9488 lib (I have a guess but easier to get verification):
Code:
			if ([COLOR="#FF0000"]SPIN1[/COLOR].pinIsMOSI(_mosi) && SPIN1.pinIsMISO(_miso) && SPIN1.pinIsSCK(_sclk)) {
				[COLOR="#FF0000"]_pspin = &SPI1;[/COLOR]
#ifdef KINETISK
				[COLOR="#FF0000"]_pkinetisk_spi = &_pspin->port();[/COLOR]

The items in red - what would they convert too. Like I said I looked have a guess, but, usually if I have a 50/50 chance I still usually guess wrong :)
 
@mjs513 - Yes, trying to keep her quiet... But she is an Ausi... So ... :D

As for code fragment, SPI integrated the same stuff as I had in SPIN (more or less)...
Adding in hacks from constructor:

Code:
		if (SPI1.pinIsMOSI(_mosi) && SPI1.pinIsMISO(_miso) && SPI1.pinIsSCK(_sclk)) {

			spi_port= &SPI1;
	 		uint32_t *pa = (uint32_t*)((void*)spi_port);
			_spi_hardware = (SPIClass::SPI_Hardware_t*)(void*)pa[1];
    			#ifdef KINETISK
			_pkinetisk_spi = (KINETISK_SPI_t *)(void*)pa[0];
			_fifo_size = _spi_hardware->queue_size;		// remember the queue size
			#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
			_pimxrt_spi = (IMXRT_LPSPI_t *)(void*)pa[0];
			#endif

I would probably do most of the extra stuff after also checking SPI2... Again if they are appropriate....

Now back to the girl
 
@KurtE and @defragster

If you all want to laugh. The 9488 library seems to work fine on a 9341 display as well as long as you remember to change the screen resolution in the .h file. It was one of those things that I had to try.

I noted that early on and since - usable data showed on the display - constraints and colors were the issues

From March 7th - not the first post it showed usable data - as soon as 9488 lib was released - I ran that code with 9341 plugged in and saw that

... Posted before that the ILI9341 worked with wrong colors using the 9488 working 18 bit code and - it also works with this change to "16 bit" only now the colors are just mostly grays and a muted yellow on the Groop testText().
...
 
Last edited:
Back
Top