Buydisplay 10.1" TFT in parallel 8080 mode and Teensy FlexIO

wwatson

Well-known member
Well I finally ordered the Buydisplay ER-TFTM101-1 with capacitive touch and had it configured for parallel communication in 8080 mode. Using parts of @Rezo's ILI984x_t41_p library, I was able to adapt my Ra8876LiteTeensy library to use the FlexIO library in 8080 parallel mode. I have been wanting to try this for a long time:D It took me a couple of weeks to get it working due to a bad breadboard. It so happens that pin 19 on the Teensy41 was plugged into one of the breadboards holes that had a broken terminal. Pin 19 is the "DB0" data line that connects to pin 15 of the 40 pin connector on the display. No matter what I wrote to the display bit 0 was always 0 and if I connected a 10K pullup to that pin it always was always 1. It was the pin hole where I had plugged in the jumper wire next to the pin hole that pin 19 of the Teensy was plugged into. The terminal inside was broken. I finally got smart and ohm checked between pin 15 on the 40 pin connector of the display and pin 19 of the Teensy. It was an open circuit. Lesson learned, don't spend two weeks trying to guess what the problem is before checking the basics:mad:
The proof of function:
IMG_20240311_123543064_HDR.jpg

The mess of wires:
IMG_20240311_123656462.jpg


There is still a lot to do yet like setting up Multibeat reads and writes using DMA and such. Also wiring and testing the touch screen needs to be done.
Once I have the RA8876LiteTeensy library in a reasonable state I will create another branch for it on GitHub for anybody that might be interested in using it...
And thanks @Rezo and others for your work on FlexIO in 8080 mode:D
 
That looks impressive!! Whats the resolution on that?

I see you are wired in an 8 bit bus, and you mentioned DMA (which the original lib didn’t support as it used FlexIO3)
I assume you split the data on FlexIO1 or FlexIO2 port?

BTW a logic analyzer would have helped you catch that breadboard issue a bit faster!
 
Last edited:
That looks impressive!! Whats the resolution on that?

I see you are wired in an 8 bit bus, and you mentioned DMA (which the original lib didn’t support as it used FlexIO3)
I assume you split the data on FlexIO1 or FlexIO2 port?
Hi Rezo, it's 1024x600. It is a good display. My vision is not good enough for anything much smaller than this display. I have not set up DMA yet. It is still using FlexIO3. Still not that familiar with using FlexIO with DMA. More to learn and play with I guess.
I have it does running well at 40Mhz. The "_baud_div" variable is set to 4 trying for 50Mhz if that is valid or not and it seems to run fine. I'm sure it would run faster using a 16bit transfer. That will be my next adventure. I have learned a lot about FlexIO by using your library and and other resources.
Much more to play with...
 
You can look at my other library, the one that works with the Teensy Micromod - it uses FlexIO2 and DMA.
On the T4.0 and 4.1 there are not enough consecutive pins to support even an 8 bit bus. So if you want, you can try the MicroMod with an ATP board and you'll see a boost in performance if you need to do other tasks while writing to the display.
But if you want to stick to the 4.1 for now, defiantly try out 16 bit mode - it won't have DMA (only supports transferring up to 32 bytes before it triggers in interrupt to load the next block of data) but it will be much faster than today.
 
You can look at my other library, the one that works with the Teensy Micromod - it uses FlexIO2 and DMA.
On the T4.0 and 4.1 there are not enough consecutive pins to support even an 8 bit bus. So if you want, you can try the MicroMod with an ATP board and you'll see a boost in performance if you need to do other tasks while writing to the display.
But if you want to stick to the 4.1 for now, defiantly try out 16 bit mode - it won't have DMA (only supports transferring up to 32 bytes before it triggers in interrupt to load the next block of data) but it will be much faster than today.
Sorry for The late reply, Thanks for the clarification. I will probably wire up the T4.1 for 16 bit first and then and test the MicroMod ATP. Right now I am a little frustrated trying to figure out the Teensy software pin numbering as associated with the actual ATP headers?? I tried using @KurtE's pinout sheet for the MicroMod but that seems to be for the M.2 connector. I have spent all morning searching the internet for some sort of ATP header information that associates with Teensy software pin numbering. Is that available? What info am I missing? I was able to find the header "Jx" numbers.
Thanks
 
Sorry for The late reply, Thanks for the clarification. I will probably wire up the T4.1 for 16 bit first and then and test the MicroMod ATP. Right now I am a little frustrated trying to figure out the Teensy software pin numbering as associated with the actual ATP headers?? I tried using @KurtE's pinout sheet for the MicroMod but that seems to be for the M.2 connector. I have spent all morning searching the internet for some sort of ATP header information that associates with Teensy software pin numbering. Is that available? What info am I missing? I was able to find the header "Jx" numbers.
Thanks
Funy you should mention it... I believe one or more of the pages has the ATP pins on them as well...
I just so happens, as I mentioned up on the thread about fancy memory :lol:
I decided to make a quick and dirty shield for the ATP board, which I ordered a set from OSHPark... @mjs513 can verify just how dirty... They did not work too well.

So I fixed my screw ups on that board and ordered another set, this time from PCBWay. Which arrived yesterday. I just finished soldering up one and it appears to work:
1710279174575.png

The main thing that I setup on this board was to make it easy to plug in any of the Camera that Arduino now sells for the GIGA, as well as an ILI9341/ILI9448 display, SDCard (SDIO) and in theory an Audio board. So needed to rearrange which pins for Flexio and the like.

One reason I am mentioning all of this, is on 2nd attempt, I marked which IO pins on the ATP are which Teensy pin numbers
1710279573950.png


I used some images from @mjs513 to help on this.
 
@KurtE - Wow, I just finished running the blink sketch on the MMod changing the blink pin number 1 buy 1 and checking each pin with an LED to see which one was blinking. I printed out the ATP pcb image and wrote down the pin number by the corresponding pin on the diagram:) I guess I can verify my diagram with your image above. That works.A couple of questions. First I noticed that RTS and CTS don't seem to have pin numbers associated with them. Secondly the capasitive touch screen chip is a GT9271 driver. Is that compatible with Ra8876LiteTeensy library?
Thanks
 
w, I just finished running the blink sketch on the MMod changing the blink pin number 1 buy 1 and checking each pin with an LED to see which one was blinking. I printed out the ATP pcb image and wrote down the pin number by the corresponding pin on the diagram:) I guess I can verify my diagram with your image above.
Note for things like this, I end up using sketcth that @defragster and I played with a long while ago:

It sets all of the pins into either INPUT_PULLUP or INPUT_PULLDOWN. You can then take a jumper wire from either GND or 3.3v depending on which mode you are in, and touch each pin. It will display which IO pin(pins) changed state...
 

Attachments

  • HiLowTest.ino
    3.1 KB · Views: 1,318
Note for things like this, I end up using sketcth that @defragster and I played with a long while ago:
Good posting - Handy Sketch! I went looking and got distracted ... Used it with the SDRAM DevBoard to confirm the wired and 'extra' pins not connected.
 
@mjs513 - That is exactly what i was looking for.
You guys are the best :D
Thanks

Edit: That also explains why I was not seeing any signals on the "RTS-CTS" pins...
 
@Rezo - I wired up the T41 for 16bit I/O and did some basic reads and writes. All failed. I hooked up my LA to monitor the first two bits of the high byte and low byte. Was reading 0xff from the status reg which was wrong. It should read 0x50 when uninitialized and 0x54 after initialization. Turns out I have to swap the 16bit bytes for this device. It is going to be kinda tricky as this device expects 8bit transfers for registers and 8bit or 16bit transfers for memory access. After this is working the MicroMod should be easier to setup...
 
You can swap the bytes around when reading or writing by using SHIFTBUFBYS instead of SHIFTBUF
I used this even when doing 8bit writes when the buffer was loaded with 16 bits of data
 
A quick update:
I now have the T41 working with the RA8876 display in both 8-bit and 16-bit modes using the Ra8876LiteTeensy library. @Rezo was correct. The 16-bit mode is twice as fast as the 8-bit mode which makes sense when using twice as many data lines. Here are some transfer times.
8-bit:
Code:
 Teensy and RA8876 parallel 8080 mode testing (8/16)

Bus speed: 40 MHZ

Drawing two pictures at 794800 bytes in 8-bit mode

Draw time: 422ms

Press anykey to continue
and 16-bit mode:
Code:
 Teensy and RA8876 parallel 8080 mode testing (8/16)

Bus speed: 40 MHZ

Drawing two pictures at 794800 bytes in 16-bit mode

Draw time: 213ms

Press anykey to continue

Next up is setting up the MicroMod and after that is working I'll cleanup and push up the Ra8876LiteTeensy library. There are still a lot of incompatibilities in some of the methods that need to be addressed.
Note: The 4 wire SPI mode will still be usable in the Ra8876LiteTeensy library. Added define "USE_8080_IF".
 
That seems a bit long?
1024*600*2bpp / 40Mhz is 32.55FPS, which is roughly 30ms per full screen write.
How are you getting over 200ms for two 800kb images?
 
That seems a bit long?
1024*600*2bpp / 40Mhz is 32.55FPS, which is roughly 30ms per full screen write.
How are you getting over 200ms for two 800kb images?
Not really sure. Probably should run the same test program using SPI mode on my other display to compare.
Here is the sketch I am running:
Code:
#include "RA8876_t3.h"
#include "teensy41.c"
#include "Teensy41_Cardlike.h"

uint8_t dc = 13;
uint8_t cs = 11;
uint8_t rst = 12;
uint32_t start = 0;
uint32_t end =  0;

RA8876_t3 lcd = RA8876_t3(dc,cs,rst); //(dc, cs, rst)

void setup() {
  while (!Serial && millis() < 3000) {} //wait for Serial Monitor
  Serial.printf("%c Teensy and RA8876 parallel 8080 mode testing (8/16)\n",12);
//  Serial.print(CrashReport);
  pinMode(33, INPUT); // For XnWAIT signal if connected and used.

  lcd.begin(40);
  Serial.print("\nBus speed: ");
  Serial.print(40,DEC);
  Serial.println(" MHZ");
}

void loop() {
  start = millis();
  lcd.putPicture_16bppData16(544,280,480,320,teensy41);
  lcd.putPicture_16bppData16(0,0,575,424,teensy41_Cardlike);
  end = millis() - start;
  Serial.printf("\nDrawing two pictures at %d bytes in %d-bit mode\n",(153600+243800)*2,BUS_WIDTH);
  Serial.printf("\nDraw time: %dms\n\n",end);
  waitforInput();
}

void waitforInput()
{
  Serial.println("Press anykey to continue");
  while (Serial.read() == -1) ;
  while (Serial.read() != -1) ;
}
and the sequence of calls:
Code:
void  RA8876_t3::putPicture_16bppData16(ru16 x,ru16 y,ru16 width, ru16 height, const unsigned short *data)
{
    ru16 i,j;
    putPicture_16bpp(x, y, width, height);
    for(j=0;j<height;j++) {
        for(i=0;i<width;i++) {
            lcdDataWrite16bbp(*data);
            data++;
        }
    }
    checkWriteFifoEmpty();//if high speed mcu and without Xnwait check
    activeWindowXY(0,0);
    activeWindowWH(_width,_height);
}

//**************************************************************//
// support SPI interface to write 16bpp data after Regwrite 04h
//**************************************************************//
void RA8876_t3::lcdDataWrite16bbp(ru16 data, bool finalize)
{

  if(BUS_WIDTH == 8) {
    lcdDataWrite(data & 0xff);
    lcdDataWrite(data >> 8);

  } else {
    lcdDataWrite16(data, false );
  }
}

void RA8876_t3::lcdDataWrite16(uint16_t data, bool finalize)
{
  while(WR_IRQTransferDone == false) {} //Wait for any DMA transfers to complete
  FlexIO_Config_SnglBeat();
  CSLow();
  DCHigh();
  p->SHIFTBUF[0] = data;
  /*Wait for transfer to be completed */
  while(0 == (p->SHIFTSTAT & (1 << 0))) {}
  while(0 == (p->TIMSTAT & (1 << 0))) {}
  /* De-assert /CS pin */
  CSHigh();
}

Any ideas?

Edit: I think the only way it is going to be faster is to use async multibeat with DMA. So I will set that up on the MicroMod next. Still learning :)
@KurtE has async SPI with DMA setup using the BTE functions of the RA8876. I am getting 68ms transfer times with the same sketch...
 
Last edited:
Biggest issue I see is each time you write a pixel you are calling flexio config and asserting/de asserting CS/DC - thats wasted time.
In your function putPicture_16bppData16 you already have a pointer to data.
So you just write the data to the buffer in a for loop, just like in my library.
Assert CS only before and after a full image write or a single command.
Same goes for DC signal.
 
Biggest issue I see is each time you write a pixel you are calling flexio config and asserting/de asserting CS/DC - thats wasted time.
In your function putPicture_16bppData16 you already have a pointer to data.
So you just write the data to the buffer in a for loop, just like in my library.
Assert CS only before and after a full image write or a single command.
Same goes for DC signal.
That was the issue:
Code:
 Teensy and RA8876 parallel 8080 mode testing (8/16)

Bus speed: 40 MHZ
Rotate: After Origins

Drawing two pictures at 794800 bytes in 16-bit mode

Draw time: 26ms
This is the code now:
Code:
void  RA8876_t3::putPicture_16bppData16(ru16 x,ru16 y,ru16 width, ru16 height, const unsigned short *data)
{
    ru16 i,j;
    putPicture_16bpp(x, y, width, height);
#if !defined(USE_8080_IF)
    for(j=0;j<height;j++) {
        for(i=0;i<width;i++) {
            lcdDataWrite16bbp(*data);
            data++;
        }
    }
#else
  while(WR_IRQTransferDone == false) {} //Wait for any DMA transfers to complete
  FlexIO_Config_SnglBeat();
  CSLow();
  DCHigh();

  for(j=0;j<height;j++) {
    for(i=0;i<width;i++) {
      p->SHIFTBUF[0] = *data++;
      /*Wait for transfer to be completed */
      while(0 == (p->SHIFTSTAT & (1 << 0))) {}
      while(0 == (p->TIMSTAT & (1 << 0))) {}
    }
  }
  /* De-assert /CS pin */
  CSHigh();
#endif
    checkWriteFifoEmpty();//if high speed mcu and without Xnwait check
    activeWindowXY(0,0);
    activeWindowWH(_width,_height);
}
Thanks for the advice. This is a very big library hopefully I won't have to modify to much more :D
This is the library Ra8876LiteTeensy.
 
Back
Top