ST7789 display initialization issue

I'm not using Adafruit or any other library because I'm trying to write my own driver so that I can hook up my LCD to an expansion port instead of the SPI bus.

However, after a lot of try I still can't get the initialization right to display anything at all. I tried the Adafruit_ST7789 library with the same wiring just to be sure it's not a hardware problem and it worked. For now I'm hooking up the LCD to the SPI bus of my ESP8266. I'm not sure in the end whether it is the initialization, could be the SPI write function, can anyone tell what I did wrong?
Thank you in advance!

#include <SPI.h>

#define TFT_CS    15
#define TFT_DC    2
#define TFT_RST   4

#define TFT_WIDTH   135
#define TFT_HEIGHT  240

void setup() {
  Serial.begin(115200);
  SPI.begin();
  pinMode(TFT_CS, OUTPUT);
  pinMode(TFT_DC, OUTPUT);
  pinMode(TFT_RST, OUTPUT);

  digitalWrite(TFT_CS, HIGH); 
  digitalWrite(TFT_RST, HIGH);
  delay(100);
  digitalWrite(TFT_RST, LOW);
  delay(100);
  digitalWrite(TFT_RST, HIGH);

  initDisplay();
  clearScreen();
  drawPixel(10, 10, 0xF800);
  
}

void loop() {
}

void initDisplay() {
  digitalWrite(TFT_CS, LOW);
  
  // SWRESET
  writeCommand(0x01);
  delay(150);
  
  // COLMOD
  writeCommand(0x3A);
  writeData(0x55);
  delay(10);

  // INVON
  writeCommand(0x21);
  delay(10);
  
  // SLPOUT
  writeCommand(0x11);
  delay(10);
  
  // NORON
  writeCommand(0x13);
  delay(10);
  
  // DISPON
  writeCommand(0x29);
  delay(10);
  
  // MADCTL
  writeCommand(0x36);
  writeData(0x08);
  
  digitalWrite(TFT_CS, HIGH);
}

void clearScreen() {
  digitalWrite(TFT_CS, LOW);
  
  setAddrWindow(0, 0, TFT_WIDTH - 1, TFT_HEIGHT - 1);
  
  for (int i = 0; i < TFT_WIDTH * TFT_HEIGHT; i++) {
    writeColor(0x0000);
  }
  
  digitalWrite(TFT_CS, HIGH);
}

void drawPixel(int x, int y, uint16_t color) {
  digitalWrite(TFT_CS, LOW);
  
  setAddrWindow(x, y, x, y);
  writeColor(color);
  
  digitalWrite(TFT_CS, HIGH);
}

void setAddrWindow(int x0, int y0, int x1, int y1) {
  writeCommand(0x2A); // CASET (Column Address Set)
  writeData(x0 >> 8);
  writeData(x0 & 0xFF);
  writeData(x1 >> 8);
  writeData(x1 & 0xFF);
  
  writeCommand(0x2B); // RASET (Row Address Set)
  writeData(y0 >> 8);
  writeData(y0 & 0xFF);
  writeData(y1 >> 8);
  writeData(y1 & 0xFF);
  
  writeCommand(0x2C); // RAMWR (Memory Write)
}

void writeCommand(uint8_t cmd) {
  digitalWrite(TFT_DC, LOW);
  SPI.transfer(cmd);
  digitalWrite(TFT_DC, HIGH);
}

void writeData(uint8_t data) {
  SPI.transfer(data);
}

void writeColor(uint16_t color) {
  SPI.transfer(color >> 8);
  SPI.transfer(color & 0xFF);
}

But in the code below you're using the SPI bus, even in the standard configuration.

You expect us to debug code where a working library exists that does the same? Wasted time in my opinion.
You even don't tell us what is going wrong, what error you may get, etc.

Pulling CS low isn't just activating the device it's also to start and end a transaction. I'm not an expert for that chip but I guess it's working like most SPI devices that know when a new transaction start by the falling edge of the CS line.

Most probably you can eliminate most of the delay() calls though.

If you read the following paragraph, I did pointed out that I'm using SPI just as temporary use, this is just so that I can make sure I'm following the right Initialization sequence.

I don't think Adafruit library has a constructor for defining SPI pin. I did say that I'm going to hook it up to an expansion port. I'm trying to solve one problem at a time. If I had included that, its gonna add weight to the whole problem, I'm not concerned about that yet. I'm trying not to waste your time, hence why I used SPI library to minimize the issue at hand.

Thanks for pointing out the issue, I fixed a portion of the program by wrapping the write command with the CS control instead.

void writeCommand(uint8_t cmd) {
  digitalWrite(TFT_CS, LOW);
  digitalWrite(TFT_DC, LOW);
  SPI.transfer(cmd);
  digitalWrite(TFT_CS, HIGH);
}

void writeData(uint8_t data) {
  digitalWrite(TFT_CS, LOW);
  digitalWrite(TFT_DC, HIGH);
  SPI.transfer(data);
  digitalWrite(TFT_CS, HIGH);
}

But now instead of a blank screen, I got a static/glitch display. I have seen this problem before but it was a resolution issue, but the resolution is right, tested with adafruit library. I tried swapping the width and height value but no effect. Tried different configurations like pixel format and rotation, didn't work. But the command write works now as i tried some command like display off and inversion.


Ignore the writing on the breakout board, it says 0.96", but I soldered a 1.14" display to it.

When I want to re-invent things, I first use the right tools to make it work the right way. Then, in small steps, replace working tools with my code.

I looked into Adafruit library and tried copying the initialization that was used there, but at some point i lost track of what library a certain function belongs to when it comes down to data transfer. I'm not that good at C prog but I'm still trying to piece it together. Thanks for the advice.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.