RA8876LiteTeensy For Teensy T36 and T40

Dear group,

For the speed of my project I need to use external font rom ER3304_1 is this possible with the RA8876 7" display.

Best,

Johan
 
With an older version of the library I used
Code:
ExternalFontRom rom = RA8876_FONT_ROM_GT30L32S4W;
tft.initExternalFontRom(0, rom);
tft.selectExternalFont( RA8876_FONT_FAMILY_TIMES, RA8876_FONT_SIZE_16,
                RA8876_FONT_ENCODING_ASCII);
then to switch to Arial I only had to use
Code:
tft.selectExternalFont( RA8876_FONT_FAMILY_ARIAL, RA8876_FONT_SIZE_16,
                RA8876_FONT_ENCODING_ASCII);
I haven't tested with the current version of the library.
 
Not working on my RA8876 display

error: 'class RA8876_t3' has no member named 'initExternalFontRom'
35 | tft.initExternalFontRom(0, rom);

error: 'class RA8876_t3' has no member named 'selectExternalFont'

Best,
Johan
 
Here's the code from the library I've been using. The entries might be named something else in the current library:

Code:
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();
}
 
I think we must redo keywords text for the RA8876 because a lot of things are not there when I look in source files.
This is confusing so I will make a new keywords file special for the RA8876 display.

My RTTY modem works awesome on a RA8876 display.
Here the very basic setup to get something to work without hassels.

Code:
// 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 ");
  }
}

1.jpg
2.jpg
 
Last edited:
Hi group,

Is there anyone who can help with the font rom for my RTTY decoder. The thing is when using LiberationMono font and use 9 lines of text and when shifting up it not looks very nice that can better. There is simply to much delay, with the font rom we can avoid that problem and shifting very fast the lines up.


Please help!

Best,

Johan
 
"Shifting it up"? Use a scroll window or BTE function. If you're really stuck on a custom font then write the special characters to another layer and just copy layer-to-layer. Layers are actually more useful when used for their original purpose: spend time writing to a hidden layer then promote that to be visible only when you're finished.
 
Unfortunately layers are not supported in this library, I used layers a lot in the RA8875 but in the the lite version I can not find anything about layers.

Best,
Johan
 
Sorry, I was thinking of the "5" not the "6". You are correct that they are not the same thing. The "6" has pages but they're not as good as layers.
But you still have a scroll function.
 
It's also not a 6" but a 7" here I show you what I mean ... this can be a bit better.



Best regards,

Johan
 
Did you try the scroll function?
What SPI frequency did you use? I seem to remember this can go to 80MHz so long as your wiring isn't completely terrible.
 
Looks like the Lite library uses genitopCharacterRomParameter() to select the external font ROM. Something like:
Code:
genitopCharacterRomParameter(RA8876_SERIAL_FLASH_SELECT1,RA8876_SPI_DIV4,RA8876_GT30L32S4W,
                      RA8876_ASCII, RA8876_GT_VARIABLE_WIDTH_ARIAL);
or
Code:
genitopCharacterRomParameter(RA8876_SERIAL_FLASH_SELECT1,RA8876_SPI_DIV4,RA8876_GT30L32S4W,
                      RA8876_ASCII, RA8876_GT_VARIABLE_FIXED_WIDTH_ROMAN);
 
Scroll 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);
}
 
Scroll 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);
}
Glad to see you were able to optimize the scroll scroll function for your application :)

You might want to look at a newer version of RA8876liteteensy that allows you to use the parallel 8080 8/16bit communication bus. This also could be an option to improve performance as well.
There are three libraries involved of which you only need two depending on whether you are using an SPI or 8080 parallel interface and the common RA8876 library.

TeensyRA8876-GFX-Common The main RA8876 library ( Manditory).
TeensyRA8876-SPI The SPI interface library (Optional).
TeensyRA8876-8080 The 8080 parallel interface library (Optional).
Only one at a time of the interface libraries can be used with the TeensyRA8876-GFX-Common library.
 
To scroll the text as seen in the video there is a bit more needed and well my PrintandScroll_RX function see code below, here words are not broken if at end of line but copied at incoming line.

I hope other people like this for CW, PSK and RTTY modems.

73' PD0LEW
Johan




Code:
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;
    }
}
 
Last edited:
Back
Top