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.
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);
}