RA8876LiteTeensy For Teensy T36 and T40

BUT - Yep you did :D

Fixed in demo: byte order wrong:
Code:
void Ra8876_Lite::lcdDataWrite16bbp(ru16 data) 
{
	RA8876_BUSY = true;
	startSend();
	SPI.transfer(RA8876_SPI_DATAWRITE);
	SPI.transfer(data);
  SPI.transfer(data>>8);
	endSend();
	RA8876_BUSY = false;
}
The Transfer16 wrote MSB, LSB and it wants LSB, MSB...

Now if I were to do this right, would probably do a 3 element array and put the three bytes and do one transfer of 3 bytes...

Will be interesting with your experiment... But I am not sure it does any of the miring and rotating of the coordinates passed in to graphic functions. Only how those are used within the
graphic ... Could be wrong.

But again notice their clear screen still showed
Code:
//clear page1
  ra8876lite.canvasImageStartAddress(PAGE1_START_ADDR);
  ra8876lite.canvasImageWidth(SCREEN_WIDTH);
  ra8876lite.activeWindowXY(0,0);
  ra8876lite.activeWindowWH(SCREEN_WIDTH,SCREEN_HEIGHT); 
  ra8876lite.drawSquareFill(0, 0, 1023, 599, COLOR65K_BLUE);

And their graphics are squares not arbitrary rectangle. So would be interesting to see how that impacts...
 
@KurtE
1st - the change to lcdDataWrite16bbp works :) just checked

2nd - just tried drawing a rectangle while the screen was rotated, and sure enough have to swap x,y values to make it draw correctly, i.e., x along the short side and y down the long side.

Going to do a couple of edits and then post the updated sketch.
 
Sounds good.

My guess is that we need to step back and rework some of this, probably by looking at RA8875 code.

That is for example drawing a pixel on RA8875 the code is:
Code:
void RA8875::drawPixel(int16_t x, int16_t y, uint16_t color)
{
	//setXY(x,y);
	if (_textMode) _setTextMode(false);//we are in text mode?
	setXY(x,y);
	writeCommand(RA8875_MRWC);
	if (_color_bpp > 8){
		writeData16(color); 
	} else {//TOTEST:layer bug workaround for 8bit color!
		_writeData(_color16To8bpp(color)); 
	}
}
Now if we look at setXY
Code:
void RA8875::setXY(int16_t x, int16_t y) 
{
	setX(x);
	setY(y);
}

/**************************************************************************/
/*!		
		Set the x position for Graphic Write
		Parameters:
		x: horizontal position
*/
/**************************************************************************/
void RA8875::setX(int16_t x) 
{
	if (x < 0) x = 0;
	if (_portrait){//fix 0.69b21
		if (x >= RA8875_HEIGHT) x = RA8875_HEIGHT-1;
		_writeRegister(RA8875_CURV0, x & 0xFF);
		_writeRegister(RA8875_CURV0+1, x >> 8);
	} else {
		if (x >= RA8875_WIDTH) x = RA8875_WIDTH-1;
		_writeRegister(RA8875_CURH0, x & 0xFF);
		_writeRegister(RA8875_CURH0+1, (x >> 8)); 
	}
}

/**************************************************************************/
/*!		
		Set the y position for Graphic Write
		Parameters:
		y: vertical position
*/
/**************************************************************************/
void RA8875::setY(int16_t y) 
{
	if (y < 0) y = 0;
	if (_portrait){//fix 0.69b21
		if (y >= RA8875_WIDTH) y = RA8875_WIDTH-1;
		_writeRegister(RA8875_CURH0, y & 0xFF);
		_writeRegister(RA8875_CURH0+1, (y >> 8)); 
	} else {
		if (y >= RA8875_HEIGHT) y = RA8875_HEIGHT-1;
		_writeRegister(RA8875_CURV0, y & 0xFF);
		_writeRegister(RA8875_CURV0+1, y >> 8);
	}
}

You see the code transposes the X and Y (which register is used) in the setX and SetY functions.
 
Look at setPixelCursor for the registers on the RA8876

EDIT: But and a big but. No graphic engine
Code:
/**************************************************************************/
/*!
	  draws a rectangle
	  Parameters:
	  x: horizontal start
	  y: vertical start
	  w: width
	  h: height
	  color: RGB565 color
*/
/**************************************************************************/
void RA8875::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
{
	//RA8875 it's not out-of-range tolerant so this is a workaround
	if (w < 1 || h < 1) return;//it cannot be!
	if (w < 2 && h < 2){ //render as pixel
		drawPixel(x,y,color);
	} else {			 //render as rect
		_rect_helper(x,y,(w+x)-1,(h+y)-1,color,false);//thanks the experimentalist
	}
}
 
Last edited:
Yes - that would be one place...

But also probably in all of the places like:
void RA8876_t3::drawSquareFill(ru16 x0, ru16 y0, ru16 x1, ru16 y1, ru16 color)
Code:
{
//  Serial.printf("DSF:(%d %d)(%d %d) %x\n", x0, y0, x1, y1, color);	
  check2dBusy();
  graphicMode(true);
  foreGroundColor16bpp(color);
  lcdRegDataWrite(RA8876_DLHSR0,x0, false);//68h
  lcdRegDataWrite(RA8876_DLHSR1,x0>>8, false);//69h
  lcdRegDataWrite(RA8876_DLVSR0,y0, false);//6ah
  lcdRegDataWrite(RA8876_DLVSR1,y0>>8, false);//6bh
  lcdRegDataWrite(RA8876_DLHER0,x1, false);//6ch
  lcdRegDataWrite(RA8876_DLHER1,x1>>8, false);//6dh
  lcdRegDataWrite(RA8876_DLVER0,y1, false);//6eh
  lcdRegDataWrite(RA8876_DLVER1,y1>>8, false);//6fh     
  lcdRegDataWrite(RA8876_DCR1,RA8876_DRAW_SQUARE_FILL, true);//76h,0xE0  
}
And many others, probably could/should extract to helper function, the subportion:
Code:
  lcdRegDataWrite(RA8876_DLHSR0,x0, false);//68h
  lcdRegDataWrite(RA8876_DLHSR1,x0>>8, false);//69h
  lcdRegDataWrite(RA8876_DLVSR0,y0, false);//6ah
  lcdRegDataWrite(RA8876_DLVSR1,y0>>8, false);//6bh
  lcdRegDataWrite(RA8876_DLHER0,x1, false);//6ch
  lcdRegDataWrite(RA8876_DLHER1,x1>>8, false);//6dh
  lcdRegDataWrite(RA8876_DLVER0,y1, false);//6eh
  lcdRegDataWrite(RA8876_DLVER1,y1>>8, false);//6fh

Did you want to try something like this, or ???

EDIT:

It looks like there are lots of places that maybe try to swap X, Y here that is commented out.
I believe _portrait should be false until rotate is called... and then we could uncomment all of these or we could make into function that does it for several of them.
Looks like several others need TLC with it. Like Circle, Triangle...
 
Last edited:
@KurtE
Sorry - was distracted with trying to get 180degs to work. Are we sure this is really worth it - ARGH!! have no hair left, Attached is what I have been working on:

View attachment RA8876_Lite_Graphic.zip

Wanted to get 180 working before tackling the next piece which is what you posted
 
@mjs513 - Will give it a try.

I backed up some and hacked up some and maybe making progress.

Try looking at the updated Rotate test and code up in my GIFX_ROT branch and see what you think.
 
@mjs513 - no hurry, pushed up some more changes to change Rotation(void) to setRotation(uint8_t rotation).
Put some settings in for all three. Changed example sketch that each time you enter something cycles to the next rotation.

2 of them are sort of working... 2 not yet.

Also with the swap x and y, I have not tried to do everything yet. But do have it doing the filled squares, line, Ariel text
 
@KurtE
Ok been playing with your sketch and my other test sketch. First your is looking good for incorporation. A couple of comments based on my experimentation

1. The 4th rotation CW90 can never happen - that was verified with RAIO. So only 3 possible rotations 0, CCW90, and CCW180. @MorganS confirmed this as well.
2. Using the test sketch it does the same thing with the exception that it does flip rl the image itself.
3. Tried adding a Triangle - only shows up in landscape rotations but it is rotated in the right direcion
 
@KurtE
I will take a look.

I did change a couple of things in your test:
Code:
  tft.fillRect(0, 0, 150, 50, RED);
  tft.fillRect(tft.width() - 150, 0, 150, 50, GREEN);
  tft.fillRect(tft.width() - 150, tft.height() - 50 , 150, 50, BLUE);
  tft.fillRect(0, tft.height() - 50 , 150, 50, ORCHID);
  tft.drawLine(0, 0, tft.width(), tft.height(), WHITE);
  tft.drawLine(0, tft.height(), tft.width(), 0, BLACK);
  tft.drawTriangleFill(512, 300, 475, 400, 575, 400, ORCHID);
Made your squares rectangles (wanted to see if it worked and second added triangle fill which is not working.
 
Yep - Figured Triangle would not work yet, nor circle... Have not done the swaps yet...

Will do quick update for drawTriangleFill...
 
Yep - Figured Triangle would not work yet, nor circle... Have not done the swaps yet...

Will do quick update for drawTriangleFill...

Just did the merge. Was playing with swaps - was driving me crazy so will be nice to see how you get it done. Was frustrating me this morning.
 
Just did the merge. Was playing with swaps - was driving me crazy so will be nice to see how you get it done. Was frustrating me this morning.
I had/have the Triangle one sort of working now... As well as maybe a few others.

Ellipse stuff may take longer. Also moving around where swap is done. As there are places where if X0+=X1 and Y0==Y1 it calls drawPoint, but we already swapped and then the point will swap again...


I have/had Triangle now Drawing at different location as expected. But the fill did not fill correctly. It has the right color for the start of it and then went BLACK...
If I put in a delay(25) for example after this, it fills properly. So the issue is that one of the follow on operations is NOT checking/waiting for operation to be complete before changing the foreground color.

So will isolate and see where. Then will push up next PR...
 
Oops may take me a little longer as it looks like our last set of merges I lost the the backlight() stuff...

Removed in the test updates ....
 
Merge Completed.

Made 2 changes to my version. For the triangle in the test sketch:
Code:
  int centerx = tft.width()/2;
  int centery = tft.height()/2;
  tft.drawTriangleFill(centerx, centery, centerx-100, centery+100, centerx+100, centery+100, CRIMSON);
Now it will rotate about the center which is what I screwed up to begin with otherwise I had it working :). My fault!!! as usual.

Second for rotation 2:
Code:
			VSCAN_B_to_T();
			//VSCAN_T_to_B();
Looking at the triangle it actually does pointed downwards.

EDIT: Have to fix origins for all the primitives. But need more coffee first
 
@mjs513 -

There is currently another PR to handle a few more of the primitives, at least for rotation 0 and 1,

As for rotation 2, I have a version that improves Rotation 2 (180 degrees) that is I only did a few places, and probably clean up.
But with these two changes, I have the rectangles looking like they are drawing at the right location for 180 degrees and points, which are the two primitives used for drawing the Font on the screen.
So the text looks like it updated as well.

Code:
void  RA8876_t3::setPixelCursor(ru16 x,ru16 y)
{
  	if (_portrait) swapvals(x,y);
  	[COLOR="#FF0000"]if (_rotation == 2) x = _width-x; [/COLOR]
	lcdRegDataWrite(RA8876_CURH0,x); //5fh
	lcdRegDataWrite(RA8876_CURH1,x>>8);//60h
	lcdRegDataWrite(RA8876_CURV0,y);//61h
	lcdRegDataWrite(RA8876_CURV1,y>>8);//62h
}

Code:
void RA8876_t3::drawSquareFill(ru16 x0, ru16 y0, ru16 x1, ru16 y1, ru16 color)
{
//  Serial.printf("DSF:(%d %d)(%d %d) %x\n", x0, y0, x1, y1, color);	
  check2dBusy();
  graphicMode(true);
  foreGroundColor16bpp(color);
  if (_portrait) {swapvals(x0,y0); swapvals(x1, y1);}
  i[COLOR="#FF0000"]f (_rotation == 2) {x0 = _width-x0; x1 = _width - x1;}[/COLOR]
  lcdRegDataWrite(RA8876_DLHSR0,x0, false);//68h
  lcdRegDataWrite(RA8876_DLHSR1,x0>>8, false);//69h
  lcdRegDataWrite(RA8876_DLVSR0,y0, false);//6ah
  lcdRegDataWrite(RA8876_DLVSR1,y0>>8, false);//6bh
  lcdRegDataWrite(RA8876_DLHER0,x1, false);//6ch
  lcdRegDataWrite(RA8876_DLHER1,x1>>8, false);//6dh
  lcdRegDataWrite(RA8876_DLVER0,y1, false);//6eh
  lcdRegDataWrite(RA8876_DLVER1,y1>>8, false);//6fh     
  lcdRegDataWrite(RA8876_DCR1,RA8876_DRAW_SQUARE_FILL, true);//76h,0xE0  
}
 
@KurtE
Was playing with your PR11 branch and seems to be working fine.

You beat me to it again! Just sat at the computer and was starting to go through the code to make the changes for rotation 2. :)

I will go ahead and merge PR11 into the branch so to keep it straight.
 
@KurtE
Just pushed some more rotation fixes for the graphic primitives. Did forget to update the origin fix - that's next. Eye allergies acting up so hard to see computer to make changes. Maybe later.
 
@KurtE - @wwatson - @MorganS
Just pushed the final rotation changes up to the WIP branch:
1. Updated Graphics.ino to show rotations in all 4 rotations. Had to do some editing of the sketch.
2. Updated statuline functions to support ILI-GFX fonts as those are the only fonts that can be rotated in all 4 directions.
3. Fixes for origin shifts using setOrigin
4. Made all functions standalone so they don't call off to other drawing primitives. For instance - drawRect doesn't call off to drawSquare so drawSquare if you want to use has all the clipping and rotation tests built-in.

Not sure what else to do with this now.
 
@mjs513 - Sound great.

But I am still having issues with the Rotation test sketch with Rotation 3...

May have to see what you did with the other test program. So far I am not seeing any obvious way to get this ration to work, as none of their example settings show it...

EDIT: Actually same issue on graphics test. For example status bar on same edge as Rotation 1, with text mirrored.
 
Last edited:
@mjs513 - Sound great.

But I am still having issues with the Rotation test sketch with Rotation 3...

May have to see what you did with the other test program. So far I am not seeing any obvious way to get this ration to work, as none of their example settings show it...

EDIT: Actually same issue on graphics test. For example status bar on same edge as Rotation 1, with text mirrored.

Think I know the problem - give me a bit.

EDIT: Looks like the changes I made messed a couple of other things as well. Going to take longer to sort out. But have to go out now.
 
Last edited:
Final change pushed to WIP branch. Punted on 4th rotation so set Rotation 3 to rotation 1.

Tested BTE seems to only work with Rotation 0.
 
Back
Top