Forum Rule: Always post complete source code & details to reproduce any issue!
Page 5 of 24 FirstFirst ... 3 4 5 6 7 15 ... LastLast
Results 101 to 125 of 581

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

  1. #101
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,675
    Quote Originally Posted by mjs513 View Post
    Just downloaded and gave it a go with and without @defragster's added test case.

    I tested at 30/72Mhz without any problems. I don't see any of the issues of "tearing and flashing of the screen except when the Tim's psychedelic effect hits Then I get dizzy.
    Cool. Yes, it is a bit much - color changes and fast update attempts on full screen are asking for the flash/tear, all else was smooth and good - but thought of it and somehow it works - though not sure it is properly done … it does as expected.

    Have tried some alterations and they are a big fail … on my part abusing the system … not doing right stuff in right order at right time?

  2. #102
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,675
    Will look to test on T_3.6 shortly.

    My idea to test was draw a screen with existing >> our_pallet[]

    Then shift the pallet and repeat the update by indexing through this Double pallet:
    Code:
    		uint16_t our_palletDbl[] = {
    		ILI9488_BLACK,  ILI9488_RED, ILI9488_GREEN,  ILI9488_BLUE,   ILI9488_WHITE,
    		ILI9488_YELLOW, ILI9488_ORANGE, ILI9488_CYAN, ILI9488_PINK,
    		ILI9488_BLACK,  ILI9488_RED, ILI9488_GREEN,  ILI9488_BLUE,   ILI9488_WHITE,
    		ILI9488_YELLOW, ILI9488_ORANGE, ILI9488_CYAN, ILI9488_PINK
    	};
    
    	tft.updateScreenAsync(false);
    	for (int ii = 0; ii < 8; ii++) {
    		tft.setPallet(&our_palletDbl[ii], sizeof(our_pallet) / sizeof(our_pallet[0]));
    		tft.updateScreen();
    	}
    The idea was it would recreate the PSYCHO scrolling above - by just changing the pallet association? And show that alternate pallets could be used

  3. #103
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    @... Quick update... Yes looks like image being shifted off... In test app, I disabled the dizzy stuff :lol:

    Added a section at end:
    Code:
     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();
      delay(1000);
    and if you watch the display you will see it first display the quick image and then shift over a pixel... Now to figure out fix!
    Will probably be similar to ILI9341 (where first DMA output is shortened by one pixel (3 bytes)...

    Should be fun...

    Update: before actual clicking post button.

    Hopefully fixed the offset issue... Hopefully did not hurt T4 code...

  4. #104
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @KurtE
    Just tested on the Teensy64 and without issue - didn't notice the pixel shifting but then again my eyes ain't that good Tested with the dizzy stuff still in - a lot more crazy on the T$ than the T3.6

    Update: Just loaded it up on the T3.6, new update and working no issues. I am also glad to report that it works just fine on the T$ as well - nothing broke in the translation

    Looks like its ready for a merge?

  5. #105
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    @Glad it is working - Could merge now or...

    Somethings that would maybe be nice?
    a) I have not done it yet on T3.5... There were some issues with some SPI stuff on 3.5 that was differently for the ILI9341 - Not sure if it was mainly SPI1/SPI2 issues as these only have one SPI source/dest on those...

    b) Wonder if tft.colorsArePalletIndex(true); and tft.useFrameBuffer(false); - If I should do the inverse and convert the Index into the actual color from Pallet and send it out...

    c) Need to check some more of the primitives. Did I properly handle all of the different text types: built in font, transparent, opaque and Actual font transparent and Opaque. Can we optimize the conversion of colors to indexes better...

    d) Wonder if we may want multiple Frame buffer types when we go to T4 B2?

    And at some point would be fun to have it supported on different SPI objects... Will probably try to avoid SPIN, All of the data is in SPI object, just need to get it out...

    But again merging now probably would not stop us from begin able to do the other stuff...

    So should I issue PR?

  6. #106
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    Quote Originally Posted by KurtE View Post
    @Glad it is working - Could merge now or...

    Somethings that would maybe be nice?
    a) I have not done it yet on T3.5... There were some issues with some SPI stuff on 3.5 that was differently for the ILI9341 - Not sure if it was mainly SPI1/SPI2 issues as these only have one SPI source/dest on those...

    b) Wonder if tft.colorsArePalletIndex(true); and tft.useFrameBuffer(false); - If I should do the inverse and convert the Index into the actual color from Pallet and send it out...

    c) Need to check some more of the primitives. Did I properly handle all of the different text types: built in font, transparent, opaque and Actual font transparent and Opaque. Can we optimize the conversion of colors to indexes better...

    d) Wonder if we may want multiple Frame buffer types when we go to T4 B2?

    And at some point would be fun to have it supported on different SPI objects... Will probably try to avoid SPIN, All of the data is in SPI object, just need to get it out...

    But again merging now probably would not stop us from begin able to do the other stuff...

    So should I issue PR?
    Sounds like you are having fun. But you are probably right.

    As for supporting on different SPI objects. Just did that. Pushed that change to my master the other day so the constructor is now has to be
    ILI9488_t3(&SPI, …..). For T$ only supports SPI0, for T3.5/3.6 should support all available SPI ports. Think the only thing I didn't do was a test to make sure you didn't specify as SPI object not supported by the Teensy. Know at lest for T$ and Teensy64 works when you specify SPI. Was lazy didn't test all the buses.

    I would say go ahead and do the PR so we have a baseline and then we can go with corrections/improvements going forward. To be honest either way is good for me.

    EDIT: See post #66 for spi change

  7. #107
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,675
    Nice Work KurtE Works on Teensy64_3.6!

    Thought RoundRect would be cool - not what I thought - though it does expose the CORNERS during the PSYCHO phase and shows they are respected, symmetric and maintained - i.e. nothing image shifts

    Here is the updated source for that with T64 inclusion. Hopefully the SPI SPEED will go in the Merge - it helps T_3.6 too.

    Changed on loop counter so it ends on corners not matching the outer Rect - CYAN behind Purple.
    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
    
    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);
    	tft.useFrameBuffer(true);
    	tft.setPallet(our_pallet, sizeof(our_pallet) / sizeof(our_pallet[0]));
    	tft.colorsArePalletIndex(true);
    	delay(250);
    	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
    }
    //=============================================================================
    // 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;
    	}
    	tft.updateScreenAsync();  // Try an async update...
    	tft.waitUpdateAsyncComplete();
    	if (1) {
    		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(0, 0, tft.width(), i * (tft.height() / 16));
    			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 = 0; i < (sizeof(our_pallet) / sizeof(our_pallet[0])); i++) {
    					if ( kk < 4 )
    						tft.fillRoundRect(x, y, tft.width() - x * 2, tft.height() - y * 2, 12, ((jj + i) % 9));
    					else
    						tft.fillRoundRect(x, y, tft.width() - x * 2, tft.height() - y * 2, 12, ((18 + (jj - i)) % 9));
    					x += tft.width() / 16;
    					y += tft.height() / 16;
    				}
    			}
    			tft.updateScreen();
    			tft.waitUpdateAsyncComplete();
    			//delay(5);
    		}
    	}
    	delay(1500);
    }

  8. #108
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    @mjs513 - Started to do PR, but says it can not automerge... Not sure how many conflicts?

    Can still do and then you or (I think I can maybe) do fix of it... Or I could try sync your main branch to mine, probably create a new branch merge in my current stuff and then do PR...

    As for a question earlier about being able to do SPIN stuff without SPIN... Here is a hacked up program to get the data from SPI... Currently only setup for KINETISK...

    Code:
    #include <SPI.h>
    
    void printSPIInfo(uint8_t spi_index, SPIClass *pspi) {
      pspi->begin(); // do begin to not have us die when look at registers
      Serial.printf("SPI%d Info (%x)\n", spi_index, (uint32_t)pspi);
      uint32_t *pa = (uint32_t*)((void*)pspi);
    #ifdef KINETISK
      KINETISK_SPI_t *_ps = (KINETISK_SPI_t*)(void*)pa[0];
      SPIClass::SPI_Hardware_t *_ph = (SPIClass::SPI_Hardware_t*)(void*)pa[1];
      Serial.printf("_pkinetisk_spi=%x SPIClass::SPI_Hardware_t=%x\n", (uint32_t)_ps, 
          (uint32_t)_ph);
      Serial.flush();
      Serial.printf("Queue size:%d tx dma:%d rx dma:%d\n", _ph->queue_size, _ph->tx_dma_channel, 
        _ph->rx_dma_channel);
      Serial.printf("SPI MCR:%x SR:%x\n", _ps->MCR, _ps->SR); 
    
    #elif defined(__IMXRT1052__) || defined(__IMXRT1062__)  // Teensy 4.x
    
      IMXRT_LPSPI_t *_ps = (IMXRT_LPSPI_t*)(void*)pa[0];
      SPIClass::SPI_Hardware_t *_ph = (SPIClass::SPI_Hardware_t*)(void*)pa[1];
      Serial.printf("IMXRT_LPSPI_t=%x SPIClass::SPI_Hardware_t=%x\n", (uint32_t)_ps, 
          (uint32_t)_ph);
      Serial.flush();
      Serial.printf("TX dma:%d RX dma:%d\n", _ph->tx_dma_channel, _ph->rx_dma_channel);
      Serial.printf("SPI CR:%x TCR:%x\n", _ps->CR, _ps->TCR); 
    
    #endif
      Serial.println();
    }
    
    void setup() {
      while (!Serial && (millis() < 2000)) ;
      Serial.begin(115200);
      delay(1000);
      printSPIInfo(0, &SPI);
    #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
      printSPIInfo(1, &SPI1);
      printSPIInfo(2, &SPI2);
    #endif
    }
    
    void loop() {
    }
    Output on T3.6
    Code:
    SPI0 Info (1fff0730)
    _pkinetisk_spi=4002c000 SPIClass::SPI_Hardware_t=7718
    Queue size:4 tx dma:15 rx dma:14
    SPI MCR:801f0000 SR:42000000
    
    SPI1 Info (1fff0770)
    _pkinetisk_spi=4002d000 SPIClass::SPI_Hardware_t=7684
    Queue size:1 tx dma:17 rx dma:16
    SPI MCR:801f0000 SR:42000000
    
    SPI2 Info (1fff07b0) SPI0 Info (20000a68)
    IMXRT_LPSPI_t=403a0000 SPIClass::SPI_Hardware_t=20000070
    TX dma:80 RX dma:79
    SPI CR:2 TCR:1f
    Do you think it smells a little

    Edit: Updated to show T4 data as well
    T4 output:
    Code:
    _pkinetisk_spi=400ac000 SPIClass::SPI_Hardware_t=75f0
    Queue size:1 tx dma:39 rx dma:38
    SPI MCR:801f0000 SR:42000000
    [/CODE]
    Last edited by KurtE; 04-16-2019 at 12:53 AM.

  9. #109
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @KurtE
    I rewrote the SPI stuff so in the constructor call it looks like:
    Code:
    ILI9488_t3::ILI9488_t3(SPIClass *SPIWire, uint8_t cs, uint8_t dc, uint8_t rst, uint8_t mosi, uint8_t sclk, uint8_t miso)
    {
    	spi_port = SPIWire;
    #if defined(__IMXRT1052__) || defined(__IMXRT1062__)
    	_spi_port_memorymap = 0x403A0000;
    #elif defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
    	if ( SPIWire == (SPIClass*)&SPI ) _spi_port_memorymap = 0x4002C000;
    	if ( SPIWire == (SPIClass*)&SPI1 ) _spi_port_memorymap = 0x4002D000;
    	if ( SPIWire == (SPIClass*)&SPI2 ) _spi_port_memorymap = 0x400AC000;
    #elif defined(KINETISL)
    	if ( SPIWire == (SPIClass*)&SPI ) _spi_port_memorymap = 0x40076000;
    	if ( SPIWire == (SPIClass*)&SPI1 ) _spi_port_memorymap = 0x40077000;
    #endif
    	_cs   = cs;
    ....
    Then in the functions for example:
    Code:
    uint8_t ILI9488_t3::readcommand8(uint8_t c, uint8_t index)
    {
        // Bail if not valid miso
        if (_miso == 0xff) return 0;
    
     #ifdef KINETISK
        uint16_t wTimeout = 0xffff;
        uint8_t r=0;
    
        beginSPITransaction();
        while ((((*(KINETISK_SPI_t *)_spi_port_memorymap).SR) & (15 << 12)) && (--wTimeout)) ; // wait until empty
    
        // Make sure the last frame has been sent...
        (*(KINETISK_SPI_t *)_spi_port_memorymap).SR = SPI_SR_TCF;   // dlear it out;
        wTimeout = 0xffff;
        while (!(((*(KINETISK_SPI_t *)_spi_port_memorymap).SR) & SPI_SR_TCF) && (--wTimeout)) ; // wait until it says the last frame completed
    ...
    Maybe this is why it doesn't want to merge.

    I have no clue about GitHub to be honest - I usually do the last way you mentioned.

  10. #110
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,675
    Good luck with merging ... CodeCompare is really good for manually merging and @mjs513 has done some good work there.

    ... wanted to go back to the test with exec times displayed ... where I added SPI SPEED … had to copy the code from forum … The TSET works so well in GitHub I can create new Sketches at will … which is why I put that 'file info' line in setup() ...

    Anyhow returned to :: ILI9488_t3-Support-for-the-ILI9488-on-T3-x-and-beyond on prior page.

    T$:
    T:\tCode\T4\keFBP8test\keFBP8test.ino Apr 15 2019 18:18:28
    ILI9488_SPICLOCK @ 72000000
    Reg: 979,634
    FB: 10,9047
    AS:536
    Reg: 981,288
    FBvoid: 1,043,794
    ASwt:116,072
    And Teensy64_3.6:
    ILI9488_SPICLOCK @ 64000000
    Reg: 1,369,879
    FB: 166,995
    AS:3060
    Reg: 1,369,879
    FBvoid: 1,398,228
    ASwt:136,789
    Speaking of TSet's 'NEW' ... Have not mentioned lately how cool Sublime is with TSet and FrankB's Compile.cmd. Not just not having to OPEN the IDE ever, but so cool how it plops the big red error text right by the line the compiler barfs on. And since TyComm adds the MCU name to the HEX - once you point it to a Teensy it goes there - even with two Teensy's running the same sketch.

    <edit> added the commas above for readability - but didn't read the values until posting ... the T$ does good work here versus the T_3.6 at 256 MHz. Then thanks to SPI speed I see I had the labels backwards?

    <edit2> Not sure there is a good answer [dump buffer on Odd rotation count?] but screen rotation with active buffer is great on 180's - but +/- 90 is garbage. Something happens though even rotating/displaying through 1>2>3 leaves artifacts. Not that that is needed - just odd.

    That was just 'at hand' for something to test common functions.

    Running for hours at posted higher speeds both of the prior samples are dong well - no mystery white screens or oddity.
    Last edited by defragster; 04-16-2019 at 08:34 AM.

  11. #111
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @KurtE and @defragster and others

    Incorporated the Pallet changes into the master as well as @defrages SPIClock changes into the .h file. Just be forewarned your constructor needs to change if you pull the master:
    Code:
    #if defined(__MK66FX1M0__) && !defined(TEENSY64)
    #define TFT_RST 255
    #define TFT_DC 20
    #define TFT_CS 21
    ILI9488_t3n tft = ILI9488_t3n(&SPI, TFT_CS, TFT_DC, TFT_RST);
    #elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
    // On Teensy 4 beta with Paul's breakout out:
    // Using pins (MOSI, MISO, SCK which are labeled on Audio board breakout location
    // which are not in the Normal processor positions
    // Also DC=10(CS), CS=9(BCLK) and RST 23(MCLK)
    #define TFT_RST 23
    #define TFT_DC 9
    #define TFT_CS 10
    ILI9488_t3 tft = ILI9488_t3(&SPI, TFT_CS, TFT_DC, TFT_RST);
    #elif defined(TEENSY64)
    #define TFT_RST 255
    #define TFT_DC 20
    #define TFT_CS 21
    #define TFT_SCK 14
    #define TFT_MISO 39
    #define TFT_MOSI 28
    ILI9488_t3 tft = ILI9488_t3(&SPI, TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);
    #else
    #error "This example App will only work with Teensy 3.6 or Teensy 4."
    #endif
    You should now be able to use any SPI on the T3.6 or T3.5 once that is sorted out.

  12. #112
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @defragster and @KurtE

    I updated the buddhabrot sketch to use framebuffer but no color palette since I am using a color ramp and it seems to drawing no problem. Here is the sketch changes - hope I did framebuffer stuff correctly.

    Code:
    // Buddhabrot
    // j.tarbell   January, 2004
    // Albuquerque, New Mexico
    // complexification.net
    //  http://www.complexification.net/gallery/machines/buddhabrot/appletl/index.html
    // based on code by Paul Bourke
    // astronomy.swin.edu.au/~pbourke/
    // j.tarbell   April, 2005
    //
    /*
    WRITE BMP TO SD CARD
    Jeff Thompson
    Summer 2012
    Writes pixel data to an SD card, saved as a BMP file.  Lots of code
    via the following...
    BMP header and pixel format:
       http://stackoverflow.com/a/2654860
    SD save:
       http://arduino.cc/forum/index.php?topic=112733 (lots of thanks!)
    ... and the SdFat example files too
    www.jeffreythompson.org
    */
    // Modified to run on Teensy
    // MJS     March, 2019
    
    #include <ILI9488_t3.h> // Hardware-specific library
    #include <SD.h>
    #include <SPI.h>
    #include <ili9488_t3_font_Arial.h>
    
    #define ILI9488_RST 23 //23 for t4
    #define ILI9488_DC 9
    #define ILI9488_CS 10
    ILI9488_t3 tft = ILI9488_t3(&SPI, ILI9488_CS, ILI9488_DC, ILI9488_RST);
    
    
    const int dim = 320;             // screen dimensions (square window)
    int bailout = 200;         // number of iterations before bail
    int plots = 10000;        // number of plots to execute per frame (x30 = plots per second)
    
    // 2D array to hold exposure values
    byte exposure[dim*dim];
    int maxexposure;           // maximum exposure value
    int time = 0;
    int exposures = 0;
    
    boolean drawing;
    
    //bmp save
    char name[] = "9px_0000.bmp";       // filename convention (will auto-increment)
    const int w = dim;                   // image width in pixels
    const int h = dim;                    // " height
    const boolean debugPrint = true;    // print details of process over serial?
    
    const int imgSize = w*h;
    // set fileSize (used in bmp header)
    int rowSize = 4 * ((3*w + 3)/4);      // how many bytes in the row (used to create padding)
    int fileSize = 54 + h*rowSize;        // headers (54 bytes) + pixel data
    
    unsigned char *img = NULL;
    
    File file;
    const int cardPin = 18;          // pin that the SD is connected to (d8 for SparkFun MicroSD shield)
    
    void setup() {
      Serial.begin(115200);
      tft.begin();
      tft.setRotation(3);
      tft.setFont(Arial_9);
      tft.fillScreen(ILI9488_BLACK);
      tft.setTextColor(ILI9488_WHITE, ILI9488_BLACK);
      tft.setTextDatum(TL_DATUM);
    
      if ( ARM_DWT_CYCCNT == ARM_DWT_CYCCNT ) {
        ARM_DEMCR |= ARM_DEMCR_TRCENA; // T_3.x only needs this
        ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
        Serial.println("CycleCnt Started.");
      }
      
      // SD setup
      Serial.begin(9600);
      Serial.print("Initializing SD card...");
      //if (!SD.begin(cardPin)) {
      //  Serial.println("initialization failed!");
      //  return;
      //}
      Serial.println("initialization done.");
      tft.useFrameBuffer(true);
      tft.colorsArePalletIndex(false);
    
    }
    
    uint32_t CCdiff;
    void loop() {
      plotPlots();
      static int Dexposures = 0;
      time++;
      if (time % 30 == 0) {
        // show progress every 2 seconds or so...
        CCdiff = ARM_DWT_CYCCNT;
        findMaxExposure();
        CCdiff = ARM_DWT_CYCCNT - CCdiff;
        renderBrot();
        //saveBMP();
        // show exposure value
        tft.drawString("bailout:  ", 0, 0);
        tft.drawNumber(bailout, 0, 25);
        tft.drawString("exposures: ", 0, 40);
        tft.drawNumber(exposures, 0, 60);
        tft.drawNumber(exposures - Dexposures, 0, 80);
        tft.drawString("Cycles: ", 0, 100);
        tft.drawNumber(CCdiff, 0, 120);
        tft.updateScreen();
    
        Dexposures = exposures;
      }
    
      if ( exposures > 10000000 ) {
        exposures = 0;
        memset(exposure, 0, sizeof( exposure ));
      }
    }
    
    void plotPlots() {
      float x, y;
      // iterate through some plots
      for (int n=0;n<plots;n++) {
        // Choose a random point in same range
        x = randomFloat(-2.0,1.0);
        y = randomFloat(-1.5,1.5);
        if (iterate(x,y,false)) {
          iterate(x,y,true);
          exposures++;
        }
      }
    }
    
    
    //   Iterate the Mandelbrot and return TRUE if the point exits
    //   Also handle the drawing of the exit points
    boolean iterate(float x0, float y0, boolean drawIt) {
      float x = 0;
      float y = 0;
      float xnew, ynew;
      int ix,iy;
    
      for (int i=0;i<bailout;i++) {
        xnew = x * x - y * y + x0;
        ynew = 2 * x * y + y0;
        if (drawIt && (i > 3)) {
          ix = int(dim * (xnew + 2.0) / 3.0);
          iy = int(dim * (ynew + 1.5) / 3.0);
          if (ix >= 0 && iy >= 0 && ix < dim && iy < dim) {
            // rotate and expose point
            exposure[ix*dim+iy]++;
          }
        }
        if ((xnew*xnew + ynew*ynew) > 4) {
          // escapes
          return true;
        }
        x = xnew;
        y = ynew;
      }
      // does not escape
      return false;
    }
    
    void findMaxExposure() {
      // assume no exposure
      maxexposure=0;
      // find the largest density value
      for (int i=0;i<dim;i++) {
        for (int j=0;j<dim;j++) {
          maxexposure = max(maxexposure,exposure[i*dim+j]);
        }
      }
    }
    
    
    void renderBrot() {
      // draw to screen
      for (int i=0;i<dim;i++) {
        for (int j=0;j<dim;j++) {
          float ramp = exposure[i*dim+j] / (maxexposure / 2.5);
          
          // blow out ultra bright regions
          if (ramp > 3)  {
            ramp = 1;
          }
          uint16_t color = tft.color565(int(ramp*128), int(ramp*128), int(ramp*255));
          tft.drawPixel(j+80, i, color);
    
          //color c = color(int(ramp*255), int(ramp*255), int(ramp*255));
          //set(j,i,c);
        }
      }
        tft.updateScreen();
    }
    
    double randomFloat(float minf, float maxf)
    {
      return minf + random(1UL << 31) * (maxf - minf) / (1UL << 31);  // use 1ULL<<63 for max double values)
    }
    
    void saveBMP(){
      // if name exists, create new filename
      for (int i=0; i<10000; i++) {
        name[4] = (i/1000)%10 + '0';    // thousands place
        name[5] = (i/100)%10 + '0';     // hundreds
        name[6] = (i/10)%10 + '0';      // tens
        name[7] = i%10 + '0';           // ones
        file = SD.open(name, O_CREAT | O_EXCL | O_WRITE);
        if (file) {
          break;
        }
      }
    
      // set fileSize (used in bmp header)
      int rowSize = 4 * ((3*w + 3)/4);      // how many bytes in the row (used to create padding)
      int fileSize = 54 + h*rowSize;        // headers (54 bytes) + pixel data
    
      img = (unsigned char *)malloc(3*w*h);
      
      for (int i=0;i<dim;i++) {
        for (int j=0;j<dim;j++) {
          float ramp = exposure[i*dim+j] / (maxexposure / 2.5);
          
          // blow out ultra bright regions
          if (ramp > 3)  {
            ramp = 1;
          }
          //uint16_t color = tft.color565(int(ramp*128), int(ramp*128), int(ramp*255));
          //tft.drawPixel(j+80, i, color);
          img[(j*w + i)*3+0] = (unsigned char)(int(ramp*255));    // B
          img[(j*w + i)*3+1] = (unsigned char)(int(ramp*128));    // G
          img[(j*w + i)*3+2] = (unsigned char)(int(ramp*128));    // R
          
          // padding (the 4th byte) will be added later as needed...
          //color c = color(int(ramp*255), int(ramp*255), int(ramp*255));
          //set(j,i,c);
        }
      }
    
      // create padding (based on the number of pixels in a row
      unsigned char bmpPad[rowSize - 3*w];
      for (int i=0; i<sizeof(bmpPad); i++) {         // fill with 0s
        bmpPad[i] = 0;
      }
    
      // create file headers (also taken from StackOverflow example)
      unsigned char bmpFileHeader[14] = {            // file header (always starts with BM!)
        'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0   };
      unsigned char bmpInfoHeader[40] = {            // info about the file (size, etc)
        40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0   };
    
      bmpFileHeader[ 2] = (unsigned char)(fileSize      );
      bmpFileHeader[ 3] = (unsigned char)(fileSize >>  8);
      bmpFileHeader[ 4] = (unsigned char)(fileSize >> 16);
      bmpFileHeader[ 5] = (unsigned char)(fileSize >> 24);
    
      bmpInfoHeader[ 4] = (unsigned char)(       dim      );
      bmpInfoHeader[ 5] = (unsigned char)(       dim >>  8);
      bmpInfoHeader[ 6] = (unsigned char)(       dim >> 16);
      bmpInfoHeader[ 7] = (unsigned char)(       w >> 24);
      bmpInfoHeader[ 8] = (unsigned char)(       h      );
      bmpInfoHeader[ 9] = (unsigned char)(       h >>  8);
      bmpInfoHeader[10] = (unsigned char)(       h >> 16);
      bmpInfoHeader[11] = (unsigned char)(       h >> 24);
    
      // write the file (thanks forum!)
      file.write(bmpFileHeader, sizeof(bmpFileHeader));    // write file header
      file.write(bmpInfoHeader, sizeof(bmpInfoHeader));    // " info header
    
      for (int i=0; i<h; i++) {                            // iterate image array
        file.write(img+(w*(h-i-1)*3), 3*w);                // write px data
        file.write(bmpPad, (4-(w*3)%4)%4);                 // and padding as needed
      }
      free(img);
      file.close();                                        // close file when done writing
    }

  13. #113
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    @mjs513 and @defragster and ...

    Thanks for doing the merge. I started it yesterday, but then found you had moved many of the internal macros (inline functions) from the header file into the c++ file and the merge programs were getting a little confused on what parts went where...

    The last quick and dirty test for DMA is still working on T3.6... After adding in the &SPI...

    Looks like the new stuff needs some more editing for different SPI ports... Example:
    Code:
    #elif defined(__MK66FX1M0__) 
    	_dmasettings[0].sourceBuffer(&_dma_pixel_buffer0[3], sizeof(_dma_pixel_buffer0)-3);
    	_dmasettings[0].destination(KINETISK_SPI0.PUSHR);
    	_dmasettings[0].TCD->ATTR_DST = 0;
    	_dmasettings[0].replaceSettingsOnCompletion(_dmasettings[1]);
    	_dmasettings[0].interruptAtCompletion();
    Which should be easy, just need to edit the new areas to repalce things like IMXRT_LPSPI4_S. or KINETISK_SPI0. with your new equivalent The more interesting part is in the function updateScreenAsync or initDMASettings on lines like:
    (T4) _dmatx.triggerAtHardwareEvent(DMAMUX_SOURCE_LPSPI4 _TX );
    (T3.6) _dmatx.triggerAtHardwareEvent(DMAMUX_SOURCE_SPI0_T X);

    The values of things like: DMAMUX_SOURCE_LPSPI4_TX are specific to each SPI port... Which is why I was playing around with that Hack program in #108...
    As you can see from the output for T3.6:
    Code:
    SPI0 Info (1fff0730)
    _pkinetisk_spi=4002c000 SPIClass::SPI_Hardware_t=7718
    Queue size:4 tx dma:15 rx dma:14
    SPI MCR:801f0000 SR:42000000
    
    SPI1 Info (1fff0770)
    _pkinetisk_spi=4002d000 SPIClass::SPI_Hardware_t=7684
    Queue size:1 tx dma:17 rx dma:16
    SPI MCR:801f0000 SR:42000000
    
    SPI2 Info (1fff07b0) SPI0 Info (20000a68)
    IMXRT_LPSPI_t=403a0000 SPIClass::SPI_Hardware_t=20000070
    TX dma:80 RX dma:79
    SPI CR:2 TCR:1f
    That the TX DMA sources are different for SPI it is 15, for SPI1 17 SPI2 80...

    Will start playing Maybe some of the quick updates there...

    Question for us... Should this run on a T3.2? Obviously the Frame buffer code would not work with it, but the rest could...

  14. #114
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    Hi @mjs513...

    I was doing some hacking to update the rest of the conversion to multiple SPI busses... Which I will push up soon.

    Note: I updated some of your constructor code and wanted your thoughts... So far only KinetisK...

    I hate magic numbers:
    Code:
    #if defined(__IMXRT1052__) || defined(__IMXRT1062__)
    	_spi_port_memorymap = 0x403A0000;
    #elif defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
    	if ( SPIWire == (SPIClass*)&SPI ) _spi_port_memorymap = (uint32_t)&KINETISK_SPI0;  // 0x4002C000;
        #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
    	if ( SPIWire == (SPIClass*)&SPI1 ) _spi_port_memorymap = (uint32_t)&KINETISK_SPI1; //0x4002D000;
    	if ( SPIWire == (SPIClass*)&SPI2 ) _spi_port_memorymap = (uint32_t)&KINETISK_SPI2; //0x400AC000;
    	#endif
    #elif defined(KINETISL)
    	if ( SPIWire == (SPIClass*)&SPI ) _spi_port_memorymap = 0x40076000;
    	if ( SPIWire == (SPIClass*)&SPI1 ) _spi_port_memorymap = 0x40077000;
    #endif
    Also updated that part as T3.2 does not have SPI1 nor SPI2, so it would not compile checking for them...

    But also then wondering which way is better to go: currently you are holding it as uint32_t so for example you have:
    (*(KINETISK_SPI_t *)_spi_port_memorymap).SR = SPI_SR_TCF;

    Versus holding the kinetisk value as a pointer (KINETISK_SPI_T *) example in member name, like: _spi_port

    Then all of the same references would be like: _spi_port->SR = SPI_SR_TCF;

    Either should work and my guess is generate the same code...

  15. #115
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @KurtE

    Missed those changes for DMA on different ports - like you said should be easier to do especially with your changes. Oh, probably have to fix queque size as well I kind of hard coded that in for now. Just remembered.

    As for the T3.2 think we should get the SPI changes fixed first on the T3.6, then verify on the T3.5 then move onto the T3.2, might as well. I know for the LC @tonton81 had all kinds of problems with the way it did SPI. So guess stick with the T3.x

    EDIT: I thought we were all magicians with getting this working

    EDIT:
    But also then wondering which way is better to go: currently you are holding it as uint32_t so for example you have:
    (*(KINETISK_SPI_t *)_spi_port_memorymap).SR = SPI_SR_TCF;

    Versus holding the kinetisk value as a pointer (KINETISK_SPI_T *) example in member name, like: _spi_port
    Probably later way - just got it working that way, not very good with pointers. Besides figured you all would improve on it going forward. I tend to take the long way around when I figure out how things work.

  16. #116
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @KurtE
    Just tried to compile for the T3.5. Think you need some more fences for when frame buffer is not specified.

    EDIT: Then I guess we need to add the dma settings for the T3.5.

  17. #117
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    @mjs513 - I did a quick PR that did some of the stuff I mentioned in previous post about using something like _pkinetisk_spi->SR

    Note sure yet if you want to Pull in yet, or after I update (Hack) for knowing which DMA Channel is needed...
    And maybe knowing the queue size (did not check to see if you have that already or not?

    I am also not a very good expert at lots of this pointer mumble jumble... But have hit many of these same issues earlier with SPIN and ILI9341_t3n...

    Then to try T3.5...

    EDIT: Question is for this additional information, should I use the hack I mentioned in grabbing this data from SPI object, or again have to know for each processor type...

  18. #118
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    Quote Originally Posted by KurtE View Post
    @mjs513 - I did a quick PR that did some of the stuff I mentioned in previous post about using something like _pkinetisk_spi->SR

    Note sure yet if you want to Pull in yet, or after I update (Hack) for knowing which DMA Channel is needed...
    And maybe knowing the queue size (did not check to see if you have that already or not?

    I am also not a very good expert at lots of this pointer mumble jumble... But have hit many of these same issues earlier with SPIN and ILI9341_t3n...

    Then to try T3.5...

    EDIT: Question is for this additional information, should I use the hack I mentioned in grabbing this data from SPI object, or again have to know for each processor type...
    As much as I hate to say this I would use the hack to get the additional information. Otherwise its looking like magic numbers again. I'll hold off the incorporating the PR until after..... I was trying to figure it out but kept running into problems so now I can see what you did for future reference.

    EDIT: Ok see what you did now and how it works. Thanks for the lesson, again...

  19. #119
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    Hi @mjs513... I put up phase two of the hack (in PR) that hopefully gets the size of the FIFO as well as the DMA channel. So far appears to work with SPI on T3.6 and 4...

    Next up try SPI1... Probably still issue with reading pixels, but...

  20. #120
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @KurtE
    Cool. Just got done with errands and Doctors and just catching up to see what I missed. You got pretty far - to me its one step at a time. As Michelangelo said to pope (at least Charlton Hesston said it) - "It will be finished when its finished!"

    I'll go ahead and pull in the PR just to so it wont starting getting conflicts

    EDIT: CHANGES MERGED

  21. #121
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    @mjs513 and ...

    Thanks,

    FYI - Just got back as well... Was at town for awhile and then at lunch...

    Just tried the simple test app with T3.6 on SPI1...
    Code:
    //=============================================================================
    //=============================================================================
    #include <ILI9488_t3.h>
    #include <ILI9488_t3_font_Arial.h>
    #include <ILI9488_t3_font_ArialBold.h>
    
    #define TRY_SPI1
    #if defined(TRY_SPI1) &&  defined(KINETISK)
    // MOSI 0, MISO 1, SCK 32
    #define TFT_RST 8
    #define TFT_DC 31
    #define TFT_CS 30 // not physical CS pin
    ILI9488_t3 tft = ILI9488_t3(&SPI1, TFT_CS, TFT_DC, TFT_RST);
    
    #else
    // MOSI 11, MISO 12, SCK 13
    #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
    
    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);
      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;
      }
      tft.updateScreenAsync();  // Try an async update...
      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();
      delay(1000); 
    }
    And it appears to be running... Note: I have not checked the readPixel/readRect code yet... figures T3.5 would be next...

  22. #122
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @KurtE and @defragster

    Cool that it works on the other SPI objects. You know eventually maybe we can update the your 9341 library then you don't have to worry about SPIN library But that's a project for another day.

    Any back to the project at hand. I just ran my scrolltest.ino sketch which uses readRect. No framebuffer/DMA/Palete. It works kind of. When it goes to scroll the last line in the scroll box the lines above are washed out - what do I mean - the text is there but the rect is comprised of alternating green and black lines. Here is my test sketch:
    Code:
    /***************************************************
      This is our GFX example for the Adafruit ILI9488 Breakout and Shield
      ----> http://www.adafruit.com/products/1651
    
      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
     ****************************************************/
    
    
    #include <SPI.h>
    #include <ILI9488_t3.h>
    #include <ILI9488_t3_font_ComicSansMS.h>
    
    #define TEENSY64
    
    // For the Adafruit shield, these are the default.
    #if defined(__MK66FX1M0__) && !defined(TEENSY64)
    #define TFT_RST 8
    #define TFT_DC 9
    #define TFT_CS 10
    ILI9488_t3 tft = ILI9488_t3(&SPI,TFT_CS, TFT_DC, TFT_RST);
    #elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
    // On Teensy 4 beta with Paul's breakout out:
    // Using pins (MOSI, MISO, SCK which are labeled on Audio board breakout location
    // which are not in the Normal processor positions
    // Also DC=10(CS), CS=9(BCLK) and RST 23(MCLK)
    #define TFT_RST 23
    #define TFT_DC 9
    #define TFT_CS 10
    ILI9488_t3 tft = ILI9488_t3(&SPI,TFT_CS, TFT_DC, TFT_RST);
    #elif defined(TEENSY64)
    #define TFT_RST 255
    #define TFT_DC 20
    #define TFT_CS 21
    #define TFT_SCK 14
    #define TFT_MISO 39
    #define TFT_MOSI 28
    ILI9488_t3 tft = ILI9488_t3(&SPI,TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);
    #else
    #error "This example App will only work with Teensy 3.6 or Teensy 4."
    #endif
    // If using the breakout, change pins as desired
    //Adafruit_ILI9488 tft = Adafruit_ILI9488(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
    
    void setup() {
    
      Serial.begin(9600);
     
      tft.begin();
    
      tft.setRotation(3);
    
      tft.fillScreen(ILI9488_BLACK);
      while (!Serial) ; 
      tft.setTextColor(ILI9488_WHITE);  tft.setTextSize(4);
      tft.enableScroll();
      tft.setScrollTextArea(0,0,120,240);
      tft.setScrollBackgroundColor(ILI9488_GREEN);
    
      tft.setCursor(180, 100);
    
      tft.setFont(ComicSansMS_12);
      tft.print("Fixed text");
    
      tft.setCursor(0, 0);
    
      tft.setTextColor(ILI9488_BLACK); 
    
      for(int i=0;i<20;i++){
        tft.print("  this is line ");
        tft.println(i);
        delay(500);
      }
    
      tft.fillScreen(ILI9488_BLACK);
      tft.setScrollTextArea(40,50,120,120);
      tft.setScrollBackgroundColor(ILI9488_GREEN);
      tft.setFont(ComicSansMS_10);
    
      tft.setTextSize(1);
      tft.setCursor(40, 50);
    
      for(int i=0;i<20;i++){
        tft.print("  this is line ");
        tft.println(i);
        delay(500);
      }
    
    
    }
    
    
    
    void loop(void) {
    
    
    }
    If I use framebuffer(true) I don't see that effect. So don't know if that is the way it works now or something is off with readRect.
    Code:
    #include <SPI.h>
    #include <ILI9488_t3.h>
    #include <ILI9488_t3_font_ComicSansMS.h>
    
    #define TEENSY64
    
    // For the Adafruit shield, these are the default.
    #if defined(__MK66FX1M0__) && !defined(TEENSY64)
    #define TFT_RST 8
    #define TFT_DC 9
    #define TFT_CS 10
    ILI9488_t3 tft = ILI9488_t3(&SPI,TFT_CS, TFT_DC, TFT_RST);
    #elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
    // On Teensy 4 beta with Paul's breakout out:
    // Using pins (MOSI, MISO, SCK which are labeled on Audio board breakout location
    // which are not in the Normal processor positions
    // Also DC=10(CS), CS=9(BCLK) and RST 23(MCLK)
    #define TFT_RST 23
    #define TFT_DC 9
    #define TFT_CS 10
    ILI9488_t3 tft = ILI9488_t3(&SPI,TFT_CS, TFT_DC, TFT_RST);
    #elif defined(TEENSY64)
    #define TFT_RST 255
    #define TFT_DC 20
    #define TFT_CS 21
    #define TFT_SCK 14
    #define TFT_MISO 39
    #define TFT_MOSI 28
    ILI9488_t3 tft = ILI9488_t3(&SPI,TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);
    #else
    #error "This example App will only work with Teensy 3.6 or Teensy 4."
    #endif
    // If using the breakout, change pins as desired
    //Adafruit_ILI9488 tft = Adafruit_ILI9488(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
    
    uint16_t our_pallet[] = {
      ILI9488_BLACK,  ILI9488_RED, ILI9488_GREEN,  ILI9488_BLUE,   ILI9488_WHITE,
      ILI9488_YELLOW, ILI9488_ORANGE, ILI9488_CYAN, ILI9488_PINK
    };
    
    void setup() {
    
      Serial.begin(9600);
     
      tft.begin();
      tft.useFrameBuffer(true);
      //tft.setPallet(our_pallet, sizeof(our_pallet) / sizeof(our_pallet[0]));
      tft.colorsArePalletIndex(false);
      tft.setRotation(3);
    
      tft.fillScreen(ILI9488_BLACK);
      while (!Serial) ; 
    
      tft.setTextColor(ILI9488_WHITE);  tft.setTextSize(4);
      tft.enableScroll();
      tft.setScrollTextArea(0,0,120,240);
      tft.setScrollBackgroundColor(ILI9488_GREEN);
    
      tft.setCursor(180, 100);
    
      tft.setFont(ComicSansMS_12);
      tft.print("Fixed text");
      tft.updateScreen();
    
      tft.setCursor(0, 0);
      tft.setTextColor(ILI9488_BLACK); 
    
      for(int i=0;i<20;i++){
        tft.print("  this is line ");
        tft.println(i);
        tft.updateScreen();
        delay(500);
      }
    
      tft.fillScreen(ILI9488_BLACK);
      tft.setScrollTextArea(40,50,120,120);
      tft.setScrollBackgroundColor(ILI9488_GREEN);
      tft.setFont(ComicSansMS_10);
    
      tft.setTextSize(1);
      tft.setCursor(40, 50);
      tft.updateScreen();
    
      for(int i=0;i<20;i++){
        tft.print("  this is line ");
        tft.println(i);
          tft.updateScreen();
    
        delay(500);
      }
      tft.updateScreen();
    }
    
    void loop(void) {
    }

  23. #123
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,098
    @KurtE and @defragster

    Same tests as in post 122 on the T$ and ran without issue with or without framebuffer.

  24. #124
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,415
    @mjs513 and @defragster - Now trying to get T3.5 to work...
    My earlier test without using Async Update does draw correctly. But first pass DMA is crashing...

    I thought I would try doing it like T3.6 knowing that it probably would not work (as did not do it that way in ILI9341_t3n...). I know that SPI1/SPI2 have to be different, but was not sure about SPI0... Looks like I need to do it without using the chaining like I did in T.6... Also may need to do dummy RX DMA as well... so next up try again that way...

    Probably tomorrow!

  25. #125
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,675
    @KurtE Too much progress to test And @mjs513 - multiple SPI to wire ...

    @mjs513 - did you make a board to Tri-State the TFT_MISO?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •