RA8875 and setRotation with 7" Adafruit Screen

Narrowboater

Active member
I have had a great deal of difficulty getting the in-built font to print in portrait mode but I have found a bodge which enables me to do what I want. I document it here in case it is of use to somebody else. It is not a rigorous piece of work.
It calls a bodge to set some registers in the RA8875. The Adafruit library code is unaware of this. Rotation is still specified as (0) but it performs as if in Portrait Mode. After this bodge functions such as drawLine need to called with the (portrait) co-ordinates of y,x not x,y ! But text is correctly shown as horizontal from a portrait perspective.

Screen: Adafruit 7"
RA8875: Adafruit via SPI
Processor: T3.6
Libraries: Adafruit as per code.
Arduino: 1.8.19
Teensyduino: 1.59
I am relative novice to C++ and no expert on Teensies so don't hesitate to say its rubbish if it is, or if there is better way.

C++:
// RA8875TEST
// 7" Adafruit screen
#define HARDSTOP while(1==1){}
#define ALL_MOSI_PINis28       28
#define ALL_MISO_PINis39       39
#define ALL_SCK_PINis27        27
#define RA8875_CS_PINis15      15
#define RA8875_RESET_PINis3     3

#include <Adafruit_GFX.h>    // Core graphics library
#include "Adafruit_RA8875.h"
#include <TeensyID.h>
union {
  uint32_t myTeensySerial;
  uint8_t serial[4];
} myId;
Adafruit_RA8875 tft1 = Adafruit_RA8875(RA8875_CS_PINis15, RA8875_RESET_PINis3);
char printBuff128 [129];

// 10-13 without the bodge
// 20-23 with the bodge
// x0-x3 is the rotation
int scenario = 22; // 10-13 20-23

char msg1[64];
char msg2[64];
// *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*
// *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*
FASTRUN void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.println("*** RA8875TEST ***");
  sprintf(printBuff128,"TIMESTAMP: %s", __TIMESTAMP__); 
  Serial.println(printBuff128);
  // CHECK THAT WE ARE ON THE CORRECT TEENSY !
  teensySN(myId.serial);
  myId.myTeensySerial = __builtin_bswap32(myId.myTeensySerial); // IS THIS NECESSARY ? !!!
  Serial.printf("TEENSY SERIAL = %d\n",myId.myTeensySerial);
  //if (myId.myTeensySerial!= 841146) {Serial.printf("WRONG TEENSY"); HARDSTOP;}

  // SPI
  SPI.setMOSI(ALL_MOSI_PINis28);
  SPI.setMISO(ALL_MISO_PINis39);
  SPI.setSCK(ALL_SCK_PINis27);   
  delay(1000);

  // TFT
  if (!tft1.begin(RA8875_800x480)) {Serial.println("RA8875A NOT FOUND!");}
  else                             {Serial.println("RA8875A Found");}

  tft1.displayOn(true);
  tft1.GPIOX(true);      // Enable TFT - display enable tied to GPIOX
  tft1.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight
  tft1.PWM1out(255);
  //setActiveWindow(1,0,220,120,240); // tft1

// SCENARIO
  if (scenario == 20) {modRegs();}
  if (scenario == 21) {modRegs();}
  if (scenario == 22) {modRegs();}
  if (scenario == 23) {modRegs();}
  tft1.fillScreen(RA8875_WHITE);
  tft1.graphicsMode();
  if (scenario == 10 || scenario == 20) {tft1.setRotation(0);}
  if (scenario == 11 || scenario == 21) {tft1.setRotation(1);}
  if (scenario == 12 || scenario == 22) {tft1.setRotation(2);}
  if (scenario == 13 || scenario == 23) {tft1.setRotation(3);}
  tft1.textMode();
  tft1.textEnlarge(1);
  tft1.textColor(RA8875_BLACK, RA8875_WHITE);

  sprintf(msg1,"HELLO %d",scenario);
  tft1.textSetCursor(150,0);
  tft1.textWrite(msg1);

  sprintf(msg2,"LINE 2");
  tft1.textSetCursor(200,100);
  tft1.textWrite(msg2);

  tft1.graphicsMode();
  tft1.drawCircle(50,100,10,RA8875_BLUE);
  tft1.drawLine(50,100,200,250,RA8875_RED);
 
// RESULTS 
  // There are only 2 effective settings of tft1.setRotation(?):
  //  tft1.setRotation(0) is "Landscape Mode" as far as Adafruit libraries are concerned.
  //  tft1.setRotation(1) is implemented as tft1.setRotation(0).
  //  tft1.setRotation(2) is "Portrait Mode" as far as Adafruit libraries are concerned, in a limited way.
  //  tft1.setRotation(3) is implemented as tft1.setRotation(0).

  //  tft1.setRotation(0) - WITHOUT BODGE
    //This is nominally LANDSCAPE MODE
    //The text origin of x,y is the top left corner (landscape)
    //The line origin of x,y is the top left corner (landscape)
    //The text appears horizontal (landscape)

  //  tft1.setRotation(0) - WITH BODGE
    //This is nominally LANDSCAPE MODE but forced into PORTRAIT by the bodge
    //The text origin of x,y is the top left corner (portrait)
    //The line origin of y,x (NOT x,y) is the top left corner (portrait)
    //The text appears horizontal (portrait)

  //  tft1.setRotation(2) - PORTRAIT MODE - line 1 missing !! - text is still LS
  //    text 0,0 is PO ??  x,y - text is vert
  //    line 0,0 is PO ??  x,y origin is bot right (in PO)

  //  tft1.setRotation(2) - PORTRAIT MODE - line 1 missing !!
  //    text 0,0 is PO bot left  x,y - text is horiz
  //    line 0,0 is PO bot right  x,y
 
  HARDSTOP
}
void loop() {}
// *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*
// TFT home grown Extensions
// *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*
void modRegs() {
  // SEE RAIO MANUAL PAGE 115
  // The RA8875 supports the 90 degree font write by setting the REG[22h] Bit4 = 1.
  // And collocating the VDIR(REG[20h] Bit2), LCD module can show the 90 degree font.
  // THE ADAFRUIT LIBRARY DOES NOT DO THIS
  writeReg(0x22,1 <<4);
  writeReg(0x20,1 <<2);
}
// *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*
void setActiveWindow(uint16_t ssxx, uint16_t syy, uint16_t exx, uint16_t eyy) { // NOT USED FOR THIS EXAMPLE
  // Set active window X
  writeReg(RA8875_HSAW0, (uint16_t)(ssxx) & 0xFF); // horizontal start point
  writeReg(RA8875_HSAW1, (uint16_t)(ssxx) >> 8);
  writeReg(RA8875_HEAW0, (uint16_t)(exx) & 0xFF); // horizontal end point
  writeReg(RA8875_HEAW1, (uint16_t)(exx) >> 8);

  // Set active window Y
  writeReg(RA8875_VSAW0, (uint16_t)(syy) & 0xFF); // vertical start point
  writeReg(RA8875_VSAW1, (uint16_t)(syy) >> 8);
  writeReg(RA8875_VEAW0, (uint16_t)(eyy) & 0xFF); // vertical end point
  writeReg(RA8875_VEAW1, (uint16_t)(eyy) >> 8);
}
// *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*
void writeReg(uint8_t reg, uint8_t val) {
  writeCommand(reg);
  writeData(val);
}
// *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*
void writeData(uint8_t d) {
uint32_t spi_speed = 12000000; //!< 12MHz
  digitalWrite(RA8875_CS_PINis15, LOW);
  //spi_begin();
  SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE0));
  SPI.transfer(RA8875_DATAWRITE);
  SPI.transfer(d);
  //spi_end();
  SPI.endTransaction();
  digitalWrite(RA8875_CS_PINis15, HIGH);
}
// *--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*
void writeCommand(uint8_t d) {
uint32_t spi_speed = 12000000; //!< 12MHz
  digitalWrite(RA8875_CS_PINis15, LOW);
  //spi_begin();
  SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE0));

  SPI.transfer(RA8875_CMDWRITE);
  SPI.transfer(d);
  //spi_end();
  SPI.endTransaction();
  digitalWrite(RA8875_CS_PINis15, HIGH);
}
 
Just to let you know there is a RA8875 that comes bundled with teensyduino. It supports rotation in 0, 1, 2 and 3 from what I remember and also allows use of ILI9341 and adafruit fonts - not just the internal fonts. Might give it a try - it is based off Sumotoy's ra8875 library.
 
And it worked without any fuss! It is too long ago to remember what problems I had before but whatever they were, they seem to have gone. Thank you again.
 
Back
Top