ExternalFontRom rom = RA8876_FONT_ROM_GT30L32S4W;
tft.initExternalFontRom(0, rom);
tft.selectExternalFont( RA8876_FONT_FAMILY_TIMES, RA8876_FONT_SIZE_16,
RA8876_FONT_ENCODING_ASCII);
tft.selectExternalFont( RA8876_FONT_FAMILY_ARIAL, RA8876_FONT_SIZE_16,
RA8876_FONT_ENCODING_ASCII);
void RA8876::initExternalFontRom(int spiIf, enum ExternalFontRom chip)
{
// See data sheet figure 16-10
// TODO: GT30L24T3Y supports FAST_READ command (0x0B) and runs at 20MHz. Are the other font chips the same?
// Find a clock divisor. Values are in the range 2..512 in steps of 2.
int divisor;
uint32_t speed = 20000; // 20MHz target speed
for (divisor = 2; divisor <= 512; divisor += 2)
{
if (m_corePll.freq / divisor <= speed)
break;
}
m_fontRomInfo.present = true;
m_fontRomInfo.spiInterface = spiIf;
m_fontRomInfo.spiClockDivisor = divisor;
m_fontRomInfo.chip = chip;
if (deBug & 0x4) {
Serial.print("External font SPI divisor: ");
Serial.println(divisor);
}
SPI.beginTransaction(m_spiSettings);
// Ensure SPI is enabled in chip config register
uint8_t ccr = readReg(RA8876_REG_CCR);
if (!(ccr & 0x02))
writeReg(RA8876_REG_CCR, ccr | 0x02);
if (deBug & 0x4) {
Serial.print("SFL_CTRL: ");
Serial.println(((spiIf & 1) << 7) | 0x14, HEX);
}
writeReg(RA8876_REG_SFL_CTRL, ((spiIf & 1) << 7) | 0x14); // Font mode, 24-bit address, standard timing, supports FAST_READ
if (deBug & 0x4) {
Serial.print("SPI_DIVSOR: ");
Serial.println((divisor >> 1) - 1, HEX);
}
writeReg(RA8876_REG_SPI_DIVSOR, (divisor >> 1) - 1);
if (deBug & 0x4) {
Serial.print("GTFNT_SEL: ");
Serial.println((chip & 0x07) << 5, HEX);
}
writeReg(RA8876_REG_GTFNT_SEL, (chip & 0x07) << 5);
SPI.endTransaction();
}
void RA8876::selectExternalFont(enum ExternalFontFamily family, enum FontSize size, enum FontEncoding enc, FontFlags flags)
{
m_fontSource = RA8876_FONT_SOURCE_EXT_ROM;
m_fontSize = size;
m_fontFlags = flags;
SPI.beginTransaction(m_spiSettings);
if (deBug & 0x4) {
Serial.print("CCR0: ");
Serial.println(0x40 | ((size & 0x03) << 4), HEX);
}
writeReg(RA8876_REG_CCR0, 0x40 | ((size & 0x03) << 4)); // Select external font ROM and size
uint8_t ccr1 = readReg(RA8876_REG_CCR1);
#ifdef TRANSPARENT
if ((ccr1 & 0x40) == 0) {
ccr1 |= 0x40; // Transparent background
writeReg(RA8876_REG_CCR1, ccr1);
}
#else
if (ccr1 & 0x40) {
ccr1 &= ~0x40; // no Transparent background
writeReg(RA8876_REG_CCR1, ccr1);
}
#endif
if (deBug & 0x4) {
Serial.print("CCR1: ");
Serial.println(ccr1, HEX);
}
if (deBug & 0x4) {
Serial.print("GTFNT_CR: ");
Serial.println((enc << 3) | (family & 0x03), HEX);
}
writeReg(RA8876_REG_GTFNT_CR, (enc << 3) | (family & 0x03)); // Character encoding and family
SPI.endTransaction();
}
// Test program for RA8876
#include <SPI.h>
#include <Wire.h>
#include <FT5206.h>
#include "RA8876_t3.h"
#include "USBHost_t36.h"
// Please use ILI9341_fonts-master
#include "font_LiberationMono.h"
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 600
#define RA8876_CS 10
#define RA8876_RESET 255
// Backlite connect pin 14 (RA8876) to 3.3V or use an ouput from Teensy PWM
RA8876_t3 tft = RA8876_t3(RA8876_CS, RA8876_RESET);
#define CTP_INT 6
uint8_t registers[FT5206_REGISTERS];
uint16_t new_coordinates[1][2];
uint8_t current_touches = 0;
uint16_t TouchX, TouchY, TouchZ;
FT5206 cts = FT5206(CTP_INT);
bool flag_touch = false;
void setup() {
cts.begin();
tft.begin(30000000);
tft.fillScreen(BLACK);
tft.setCursor(340, 300);
tft.setFont(LiberationMono_28);
tft.setTextColor(YELLOW);
tft.print(" Welcome to PJRC");
}
void loop() {
if (cts.touched()) {
cts.getTSregisters(registers);
current_touches = cts.getTScoordinates(new_coordinates, registers);
TouchX = SCREEN_WIDTH - new_coordinates[0][0];
TouchY = SCREEN_HEIGHT - new_coordinates[0][1];
TouchZ = current_touches;
cts.rearmISR();
}
if (TouchZ && !flag_touch) {
flag_touch = true;
tft.fillScreen(BLACK);
tft.setFont(LiberationMono_28);
tft.setTextColor(WHITE, BLACK);
tft.setCursor(220, 300);
tft.println(" Touchscreen is working ");
}
}
genitopCharacterRomParameter(RA8876_SERIAL_FLASH_SELECT1,RA8876_SPI_DIV4,RA8876_GT30L32S4W,
RA8876_ASCII, RA8876_GT_VARIABLE_WIDTH_ARIAL);
genitopCharacterRomParameter(RA8876_SERIAL_FLASH_SELECT1,RA8876_SPI_DIV4,RA8876_GT30L32S4W,
RA8876_ASCII, RA8876_GT_VARIABLE_FIXED_WIDTH_ROMAN);
//*************************************************************//
// Scroll Screen up with fixed 32 px lines and custom scroll window
//*************************************************************//
/*
void RA8876_t3::scroll(void) {
// Define the scroll window directly inside the library
const int SCROLL_TOP_Y = 60; // top of scroll window
const int SCROLL_BOTTOM_Y = 480; // bottom of scroll window
const int SCROLL_LEFT_X = 0;
const int SCROLL_RIGHT_X = SCREEN_WIDTH;
const int LINE_HEIGHT = 32; // fixed scroll height
// Scroll only inside the defined window
bteMemoryCopy(
currentPage,
SCREEN_WIDTH,
SCROLL_LEFT_X,
SCROLL_TOP_Y + LINE_HEIGHT, // source Y start
currentPage,
SCREEN_WIDTH,
SCROLL_LEFT_X,
pageOffset + SCROLL_TOP_Y, // destination Y start
SCROLL_RIGHT_X - SCROLL_LEFT_X,
SCROLL_BOTTOM_Y - SCROLL_TOP_Y - LINE_HEIGHT // copy height
);
// Clear the bottom line inside scroll window
drawSquareFill(
SCROLL_LEFT_X,
SCROLL_BOTTOM_Y - LINE_HEIGHT, // bottom Y start
SCROLL_RIGHT_X - 1,
SCROLL_BOTTOM_Y - 1,
_TXTBackColor
);
textColor(_TXTForeColor, _TXTBackColor);
}
Glad to see you were able to optimize the scroll scroll function for your applicationScroll many lines of text with minimal delay. I use the RA8876 for my RTTY modem with 14 lines of text and a lot of characters. To shiftup everything without hardware scroll then it looks not nice. Now with this modified code you will see nearly no delay when shifting up 14 lines of text.
Changes in RA8876_t3.cpp
Code://*************************************************************// // Scroll Screen up with fixed 32 px lines and custom scroll window //*************************************************************// /* void RA8876_t3::scroll(void) { // Define the scroll window directly inside the library const int SCROLL_TOP_Y = 60; // top of scroll window const int SCROLL_BOTTOM_Y = 480; // bottom of scroll window const int SCROLL_LEFT_X = 0; const int SCROLL_RIGHT_X = SCREEN_WIDTH; const int LINE_HEIGHT = 32; // fixed scroll height // Scroll only inside the defined window bteMemoryCopy( currentPage, SCREEN_WIDTH, SCROLL_LEFT_X, SCROLL_TOP_Y + LINE_HEIGHT, // source Y start currentPage, SCREEN_WIDTH, SCROLL_LEFT_X, pageOffset + SCROLL_TOP_Y, // destination Y start SCROLL_RIGHT_X - SCROLL_LEFT_X, SCROLL_BOTTOM_Y - SCROLL_TOP_Y - LINE_HEIGHT // copy height ); // Clear the bottom line inside scroll window drawSquareFill( SCROLL_LEFT_X, SCROLL_BOTTOM_Y - LINE_HEIGHT, // bottom Y start SCROLL_RIGHT_X - 1, SCROLL_BOTTOM_Y - 1, _TXTBackColor ); textColor(_TXTForeColor, _TXTBackColor); }
void CopyLineClean(char* dest, const char* src, size_t len) {
if (len > 67)
len = 67;
memcpy(dest, src, len);
dest[len] = '\0';
memset(dest + len + 1, 0, 66 - len - 1);
}
static void scrollLines(uint8_t copyLen) {
char* RXscroll[] = {
RXline2, RXline3, RXline4, RXline5,
RXline6, RXline7, RXline8, RXline9,
RXline10, RXline11, RXline12, RXline13
};
for (int i = 11; i > 0; i--)
memcpy(RXscroll[i], RXscroll[i - 1], copyLen);
}
// ============================================================
// -------------------- PRINT & SCROLL ------------------------
// ============================================================
void PrintAndScroll_RX(char ch) {
RX_pr_char = ch;
tft.setFont(LiberationMono_18); // 18 px font
// ---------------- NEW LINE ----------------
if (RX_pr_char == '\n') {
// Scroll up hardware by one line (32 px)
tft.scrollUp();
// Shift RAM buffers for scrolling
scrollLines(RX_WRAP_COLUMN + 1);
CopyLineClean(RXline2, RXline1, RXx);
// Reset cursor and line buffer
RXx = 0;
RXcurs = 0;
RXline1[0] = '\0';
// Clear the new bottom line (32 px)
//tft.fillRect(0, RX_LAST_LINE_Y + 2, SCREEN_WIDTH, RX_LINE_HEIGHT , BLACK);
// Draw the new bottom line, vertically centered
tft.setCursor(0, RX_LAST_LINE_Y + (RX_LINE_HEIGHT - 18) / 2);
tft.setTextColor(WHITE);
tft.print(RXline2);
return;
}
// ---------------- FILTER NON-PRINTABLE ----------------
if (RX_pr_char < 0x20 || RX_pr_char >= 0x7F)
return;
RXc1 = RX_pr_char;
if (RX_pr_char == ' ')
RXlast_space = RXx;
// ---------------- WORD WRAP ----------------
if (RXx == RX_WRAP_COLUMN) {
// Scroll hardware by 32 px
tft.scrollUp();
// Shift RAM buffers
scrollLines(RX_WRAP_COLUMN + 1);
if (RXlast_space == 0)
RXlast_space = RX_WRAP_COLUMN;
memcpy(RXline2, RXline1, RXlast_space);
RXline2[RXlast_space] = '\0';
// Clear bottom line (32 px)
tft.fillRect(0, RX_LAST_LINE_Y + 2, SCREEN_WIDTH, RX_LINE_HEIGHT , BLACK);
// Draw bottom line vertically centered
tft.setCursor(0, RX_LAST_LINE_Y + (RX_LINE_HEIGHT - 18) / 2);
tft.setTextColor(pageText);
tft.print(RXline2);
tft.setCursor(0, RX_BOTTOM_Y);
if (RXlast_space == RX_WRAP_COLUMN) {
RXline1[0] = '\0';
RXx = 0;
RXcurs = 0;
} else {
RXx = RX_WRAP_COLUMN - (RXlast_space + 1);
memmove(RXline1, &RXline1[RXlast_space + 1], RXx);
RXline1[RXx] = '\0';
tft.setTextColor(inCommingText, BLACK);
tft.print(RXline1);
RXcurs = RXx * RX_CHAR_WIDTH + RX_CHAR_WIDTH;
RXline1[RXx++] = RX_pr_char;
tft.print(RX_pr_char);
}
RXlast_space = 0;
}
// ---------------- NORMAL PRINT ----------------
else {
tft.setTextColor(inCommingText, BLACK);
tft.setCursor(RXcurs, RX_BOTTOM_Y - 1);
RXline1[RXx++] = RX_pr_char;
tft.print(RX_pr_char);
RXcurs += RX_CHAR_WIDTH;
}
}