ST7789_t3 Example Won't Compile With Teensy 4.1

mgaert

Member
I presume this is an easy answer because I didn't find anyone else with this problem. Just trying to compile the basic 'graphicstest.ino' in the PaulStoffregen/ST7789_t3 examples. This is with Arduino IDE. The compiler finds ST7789_t3 and ST7789_t3.cpp in the Arduino Libraries, where I put them. The basic error is

Code:
error: '_cs' was not declared in this scope; did you mean 'cs'?
 _cs   = cs;

That error is repeated for all the vars in:

Code:
 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
    uint8_t  _cs, _rs, _rst, _sid, _sclk;
    uint8_t colstart, rowstart;
    uint8_t pcs_data, pcs_command;
    uint32_t ctar;
    volatile uint8_t *datapin, *clkpin, *cspin, *rspin;
  #endif

I assume this code was not specifically written for T4.1 so I added the following to the defined code:
Code:
|| defined(__IMXRT1060RM__)

which didn't help.

That is the only change I made to the example code and libraries.

What the heck am I missing?

Thank you!
 
I presume this is an easy answer because I didn't find anyone else with this problem. Just trying to compile the basic 'graphicstest.ino' in the PaulStoffregen/ST7789_t3 examples. This is with Arduino IDE. The compiler finds ST7789_t3 and ST7789_t3.cpp in the Arduino Libraries, where I put them. The basic error is
It works fine for me. Have done most of our stuff with the T4.x...

Unclear what you mean by the above statement. How did you put them in the Arduino Libraries?
That is did you simply copy those two files into another directory or, did you for example install the library?

Or did you clone the directory https://github.com/PaulStoffregen/ST7735_t3 or download the zip file and install it?

That is the ST7789_t3 class is derived from ST7735_t3 class which are in the st7735_t3.h/cpp files.
If you look in the st77t3_t3.h file you will see things like:

Code:
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  uint8_t  _cs, _rs, _rst, _sid, _sclk;
  uint8_t pcs_data, pcs_command;
  uint32_t ctar;
  volatile uint8_t *datapin, *clkpin, *cspin, *rspin;

  SPIClass *_pspi = nullptr;
  uint8_t   _spi_num;          // Which buss is this spi on?
  KINETISK_SPI_t *_pkinetisk_spi;
  SPIClass::SPI_Hardware_t *_spi_hardware;
  void waitTransmitComplete(void);
  void waitTransmitComplete(uint32_t mcr);
  uint32_t _fifo_full_test;

  inline void beginSPITransaction() {
    if (_pspi) _pspi->beginTransaction(_spiSettings);
    if (cspin) *cspin = 0;
  }

  inline void endSPITransaction()
  {
    if (cspin) *cspin = 1;
    if (_pspi) _pspi->endTransaction();
  }


#endif
#if defined(__IMXRT1062__)  // Teensy 4.x
  SPIClass *_pspi = nullptr;
  uint8_t   _spi_num = 0;          // Which buss is this spi on?
  IMXRT_LPSPI_t *_pimxrt_spi = nullptr;
  SPIClass::SPI_Hardware_t *_spi_hardware;
  uint8_t _pending_rx_count = 0;
  uint32_t _spi_tcr_current = 0;
  uint32_t _tcr_dc_assert;
  uint32_t _tcr_dc_not_assert;


  void DIRECT_WRITE_LOW(volatile uint32_t * base, uint32_t mask)  __attribute__((always_inline)) {
    *(base+34) = mask;
  }
  void DIRECT_WRITE_HIGH(volatile uint32_t * base, uint32_t mask)  __attribute__((always_inline)) {
    *(base+33) = mask;
  }
 
#ifndef TCR_MASK
#define TCR_MASK  (LPSPI_TCR_PCS(3) | LPSPI_TCR_FRAMESZ(31) | LPSPI_TCR_CONT | LPSPI_TCR_RXMSK )
#endif
  void maybeUpdateTCR(uint32_t requested_tcr_state) {
  if ((_spi_tcr_current & TCR_MASK) != requested_tcr_state) {
      bool dc_state_change = (_spi_tcr_current & LPSPI_TCR_PCS(3)) != (requested_tcr_state & LPSPI_TCR_PCS(3));
      _spi_tcr_current = (_spi_tcr_current & ~TCR_MASK) | requested_tcr_state ;
      // only output when Transfer queue is empty.
      if (!dc_state_change || !_dcpinmask) {
        while ((_pimxrt_spi->FSR & 0x1f) )  ;
        _pimxrt_spi->TCR = _spi_tcr_current;  // update the TCR

      } else {
        waitTransmitComplete();
        if (requested_tcr_state & LPSPI_TCR_PCS(3)) DIRECT_WRITE_HIGH(_dcport, _dcpinmask);
        else DIRECT_WRITE_LOW(_dcport, _dcpinmask);
        _pimxrt_spi->TCR = _spi_tcr_current & ~(LPSPI_TCR_PCS(3) | LPSPI_TCR_CONT); // go ahead and update TCR anyway?  

      }
    }
  }

  inline void beginSPITransaction() {
    if (hwSPI) _pspi->beginTransaction(_spiSettings);
    if (!_dcport) _spi_tcr_current = _pimxrt_spi->TCR;  // Only if DC is on hardware CS 
    if (_csport)DIRECT_WRITE_LOW(_csport, _cspinmask);
  }

  inline void endSPITransaction() {
    if (_csport)DIRECT_WRITE_HIGH(_csport, _cspinmask);
    if (hwSPI) _pspi->endTransaction();  
  }

 
  void waitFifoNotFull(void) {
    uint32_t tmp __attribute__((unused));
    do {
        if ((_pimxrt_spi->RSR & LPSPI_RSR_RXEMPTY) == 0)  {
            tmp = _pimxrt_spi->RDR;  // Read any pending RX bytes in
            if (_pending_rx_count) _pending_rx_count--; //decrement count of bytes still levt
        }
    } while ((_pimxrt_spi->SR & LPSPI_SR_TDF) == 0) ;
 }
 void waitTransmitComplete(void)  {
    uint32_t tmp __attribute__((unused));
//    digitalWriteFast(2, HIGH);

    while (_pending_rx_count) {
        if ((_pimxrt_spi->RSR & LPSPI_RSR_RXEMPTY) == 0)  {
            tmp = _pimxrt_spi->RDR;  // Read any pending RX bytes in
            _pending_rx_count--; //decrement count of bytes still levt
        }
    }
    _pimxrt_spi->CR = LPSPI_CR_MEN | LPSPI_CR_RRF;       // Clear RX FIFO
//    digitalWriteFast(2, LOW);
}


  uint8_t  _cs, _rs, _rst, _sid, _sclk;

  uint32_t _cspinmask;
  volatile uint32_t *_csport;
  uint32_t _dcpinmask;
  volatile uint32_t *_dcport;
  uint32_t _mosipinmask;
  volatile uint32_t *_mosiport;
  uint32_t _sckpinmask;
  volatile uint32_t *_sckport;
  

  uint32_t ctar;
#endif
Notice the second section, ...
 
It works fine for me. Have done most of our stuff with the T4.x...

Unclear what you mean by the above statement. How did you put them in the Arduino Libraries?
That is did you simply copy those two files into another directory or, did you for example install the library?

Or did you clone the directory https://github.com/PaulStoffregen/ST7735_t3 or download the zip file and install it?

That is the ST7789_t3 class is derived from ST7735_t3 class which are in the st7735_t3.h/cpp files.
If you look in the st77t3_t3.h file you will see things like:

Code:
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  uint8_t  _cs, _rs, _rst, _sid, _sclk;
  uint8_t pcs_data, pcs_command;
  uint32_t ctar;
  volatile uint8_t *datapin, *clkpin, *cspin, *rspin;

  SPIClass *_pspi = nullptr;
  uint8_t   _spi_num;          // Which buss is this spi on?
  KINETISK_SPI_t *_pkinetisk_spi;
  SPIClass::SPI_Hardware_t *_spi_hardware;
  void waitTransmitComplete(void);
  void waitTransmitComplete(uint32_t mcr);
  uint32_t _fifo_full_test;

  inline void beginSPITransaction() {
    if (_pspi) _pspi->beginTransaction(_spiSettings);
    if (cspin) *cspin = 0;
  }

  inline void endSPITransaction()
  {
    if (cspin) *cspin = 1;
    if (_pspi) _pspi->endTransaction();
  }


#endif
#if defined(__IMXRT1062__)  // Teensy 4.x
  SPIClass *_pspi = nullptr;
  uint8_t   _spi_num = 0;          // Which buss is this spi on?
  IMXRT_LPSPI_t *_pimxrt_spi = nullptr;
  SPIClass::SPI_Hardware_t *_spi_hardware;
  uint8_t _pending_rx_count = 0;
  uint32_t _spi_tcr_current = 0;
  uint32_t _tcr_dc_assert;
  uint32_t _tcr_dc_not_assert;


  void DIRECT_WRITE_LOW(volatile uint32_t * base, uint32_t mask)  __attribute__((always_inline)) {
    *(base+34) = mask;
  }
  void DIRECT_WRITE_HIGH(volatile uint32_t * base, uint32_t mask)  __attribute__((always_inline)) {
    *(base+33) = mask;
  }
 
#ifndef TCR_MASK
#define TCR_MASK  (LPSPI_TCR_PCS(3) | LPSPI_TCR_FRAMESZ(31) | LPSPI_TCR_CONT | LPSPI_TCR_RXMSK )
#endif
  void maybeUpdateTCR(uint32_t requested_tcr_state) {
  if ((_spi_tcr_current & TCR_MASK) != requested_tcr_state) {
      bool dc_state_change = (_spi_tcr_current & LPSPI_TCR_PCS(3)) != (requested_tcr_state & LPSPI_TCR_PCS(3));
      _spi_tcr_current = (_spi_tcr_current & ~TCR_MASK) | requested_tcr_state ;
      // only output when Transfer queue is empty.
      if (!dc_state_change || !_dcpinmask) {
        while ((_pimxrt_spi->FSR & 0x1f) )  ;
        _pimxrt_spi->TCR = _spi_tcr_current;  // update the TCR

      } else {
        waitTransmitComplete();
        if (requested_tcr_state & LPSPI_TCR_PCS(3)) DIRECT_WRITE_HIGH(_dcport, _dcpinmask);
        else DIRECT_WRITE_LOW(_dcport, _dcpinmask);
        _pimxrt_spi->TCR = _spi_tcr_current & ~(LPSPI_TCR_PCS(3) | LPSPI_TCR_CONT); // go ahead and update TCR anyway? 

      }
    }
  }

  inline void beginSPITransaction() {
    if (hwSPI) _pspi->beginTransaction(_spiSettings);
    if (!_dcport) _spi_tcr_current = _pimxrt_spi->TCR;  // Only if DC is on hardware CS
    if (_csport)DIRECT_WRITE_LOW(_csport, _cspinmask);
  }

  inline void endSPITransaction() {
    if (_csport)DIRECT_WRITE_HIGH(_csport, _cspinmask);
    if (hwSPI) _pspi->endTransaction(); 
  }

 
  void waitFifoNotFull(void) {
    uint32_t tmp __attribute__((unused));
    do {
        if ((_pimxrt_spi->RSR & LPSPI_RSR_RXEMPTY) == 0)  {
            tmp = _pimxrt_spi->RDR;  // Read any pending RX bytes in
            if (_pending_rx_count) _pending_rx_count--; //decrement count of bytes still levt
        }
    } while ((_pimxrt_spi->SR & LPSPI_SR_TDF) == 0) ;
 }
 void waitTransmitComplete(void)  {
    uint32_t tmp __attribute__((unused));
//    digitalWriteFast(2, HIGH);

    while (_pending_rx_count) {
        if ((_pimxrt_spi->RSR & LPSPI_RSR_RXEMPTY) == 0)  {
            tmp = _pimxrt_spi->RDR;  // Read any pending RX bytes in
            _pending_rx_count--; //decrement count of bytes still levt
        }
    }
    _pimxrt_spi->CR = LPSPI_CR_MEN | LPSPI_CR_RRF;       // Clear RX FIFO
//    digitalWriteFast(2, LOW);
}


  uint8_t  _cs, _rs, _rst, _sid, _sclk;

  uint32_t _cspinmask;
  volatile uint32_t *_csport;
  uint32_t _dcpinmask;
  volatile uint32_t *_dcport;
  uint32_t _mosipinmask;
  volatile uint32_t *_mosiport;
  uint32_t _sckpinmask;
  volatile uint32_t *_sckport;
 

  uint32_t ctar;
#endif
Notice the second section, ...
I copied those two files where they could be found. So, I started over and downloaded the zip file and used the Include Library -> Add ZIP Library, same issue. I don't see that there is are st7735_t3.h/cpp files in that Github project. I tried to include some libraries in Arduino for "ST7735_t3" and "Adafruit ST7735 and ST7798 Library" and that didn't work as I was just hacking around. The error is pretty simple I just don't have the right libraries set up. There is an Adafruit Github that seems to have all of this in one place. I will try that next.

Thanks!
 
Sorry, I still do not understand your setup... That is, the github project I linked to above has the following stuff in the src directory
1732280187715.png


In cases like this, it is hard to know what is going on, without seeing more of the build output.
For example, if I open the example sketch graphicstest:
1732280550559.png

1732280773707.png

Normally I would suggest cut/paste some of the area in the output part of build. I wanted to highlight here some of the important information,
like where it found the ST7735_t3/ST7789_t3 library.

It is possible if you were just hacking around, maybe the compiler found some of the files in somewhere else.
Note: The Adafruit_st77... library depends on other libraries as well, specifically their GFX library.
 
Sorry, I still do not understand your setup... That is, the github project I linked to above has the following stuff in the src directory
View attachment 36363

In cases like this, it is hard to know what is going on, without seeing more of the build output.
For example, if I open the example sketch graphicstest:
View attachment 36364
View attachment 36365
Normally I would suggest cut/paste some of the area in the output part of build. I wanted to highlight here some of the important information,
like where it found the ST7735_t3/ST7789_t3 library.

It is possible if you were just hacking around, maybe the compiler found some of the files in somewhere else.
Note: The Adafruit_st77... library depends on other libraries as well, specifically their GFX library.
Really appreciate your help! That is not the GitHub I was using. I will review this, try again and get back.
 
Sorry, I still do not understand your setup... That is, the github project I linked to above has the following stuff in the src directory
View attachment 36363

In cases like this, it is hard to know what is going on, without seeing more of the build output.
For example, if I open the example sketch graphicstest:
View attachment 36364
View attachment 36365
Normally I would suggest cut/paste some of the area in the output part of build. I wanted to highlight here some of the important information,
like where it found the ST7735_t3/ST7789_t3 library.

It is possible if you were just hacking around, maybe the compiler found some of the files in somewhere else.
Note: The Adafruit_st77... library depends on other libraries as well, specifically their GFX library.
Welp, using the correct libraries worked perfectly, thanks again. FYI, I was using this Github:

I clearly didn't understand the ramifications.

My next task is to get this going with a larger display, 320 X 480. I think I can find the places to change to get it going. I've got the sizing right I just have to "place" the corners so everything fills the screen.

Thanks again!
 
Looks like I will need to add some sizing support to
Code:
void  ST7789_t3::init(uint16_t width, uint16_t height, uint8_t mode)
in ST7789_t3.cpp to account for a 3.5" display.
 
Which display is this? Have a link to it?

You might try the one:
// OR use this initializer (uncomment) if using a 2.0" 320x240 TFT:
//tft.init(240, 320); // Init ST7789 320x240

EDIT:
My next task is to get this going with a larger display, 320 X 480. I think I can find the places to change to get it going. I've got the sizing right I just have to "place" the corners so everything fills the screen.
What display is this? 320x480 sounds more like:
ILI9488/ILI9486
or HX8357
or ???
 
Which display is this? Have a link to it?

You might try the one:
// OR use this initializer (uncomment) if using a 2.0" 320x240 TFT:
//tft.init(240, 320); // Init ST7789 320x240

EDIT:

What display is this? 320x480 sounds more like:
ILI9488/ILI9486
or HX8357
or ???
This is the display:

There were a bunch of libraries and examples on that wiki page but they were very hardware specific and I couldn't get them to go with the Teensy (hackin' again).

Appreciated!
 
I think I got this. I added a condition in ST7798_t3::init() as follows:

Code:
} else if ((width == 320) && (height == 480)) {
    _colstart = 0;   
    _colstart2 = 0; 
    _rowstart = 0;   
    _rowstart2 = 0;

That seemed to set everything right and the test is filling the screen. If that seems like it will be trouble later please let me know!

And always, thanks!
 
Back
Top