Hi everyone !
I am trying to make connect a round LCD screen from Waveshare based ont the GC9A01 with the SPI N°4 of the Arduino Nicla Vision.
It’s a 4-Wire SPI :
MOSI → PE14 (COPI)
CLK → PE12 (SCLK)
CS → PE11 (CS)
DC → PG1 (GPIO3)
(No MISO pin needed because it’s a screen). I check several times with a multimeter that every wiring was ok. The LCD power is supplied with 5V and the SPI is supplied with 3.3V (according to the LCD datasheet it’s ok).
I found a micropython code on github that I have heavily modified for the nicla Vision.
Source from GitHub
This is a short version with just the initialization (init without GFX functions or operating functions). My holy graal is to print in the console “LCD Init end”. Display operations will come later.
import time
from micropython import const
import ustruct as struct
from pyb import Pin, SPI, delay
import sys
_DEBUG = True
def print_debug(message):
if _DEBUG : print(message)
#===================================================================================================
#Registres =========================================================================================
#===================================================================================================
# commands
GC9A01_SWRESET = const(0x01)
GC9A01_SLPIN = const(0x10)
GC9A01_SLPOUT = const(0x11)
GC9A01_INVOFF = const(0x20)
GC9A01_INVON = const(0x21)
GC9A01_DISPOFF = const(0x28)
GC9A01_DISPON = const(0x29)
GC9A01_CASET = const(0x2A)
GC9A01_RASET = const(0x2B)
GC9A01_RAMWR = const(0x2C)
GC9A01_VSCRDEF = const(0x33)
GC9A01_COLMOD = const(0x3A)
GC9A01_MADCTL = const(0x36)
GC9A01_VSCSAD = const(0x37)
# Color definitions
BLACK = const(0x0000)
BLUE = const(0x001F)
RED = const(0xF800)
GREEN = const(0x07E0)
CYAN = const(0x07FF)
MAGENTA = const(0xF81F)
YELLOW = const(0xFFE0)
WHITE = const(0xFFFF)
_ENCODE_PIXEL = ">H"
_ENCODE_POS = ">HH"
_DECODE_PIXEL = ">BBB"
_BUFFER_SIZE = const(256)
#===================================================================================================
#Classe SPI ========================================================================================
#===================================================================================================
SPI_DUMMY_INT = 0x00
SPI_TRANSFER_LEN = 1
SPI_HOLD_US = 50
class LCD_SPI:
def __init__(self) -> None:
print_debug("SPI Init Start")
self._SPICS = Pin('PE11', Pin.OUT_PP)
self._SPIDC = Pin('PG1', Pin.OUT_PP)
self._SPIRST = Pin('PA9', Pin.OUT_PP)
self._SPI = SPI(4, SPI.MASTER,baudrate = 100000)
#prescaler = 4,
#polarity = 1, #Supporte 0,0 ou 1,1
#phase = 0,
#crc=None)
#firstbit = SPI.MSB)
self.end()
print_debug("SPI Init End")
def start(self) -> None:
self._SPICS.low()
time.sleep_us(SPI_HOLD_US) # type: ignore
def end(self) -> None:
self._SPICS.high()
#self._SPIDC.high()
time.sleep_us(SPI_HOLD_US) # type: ignore
def command(self, command=None) -> Optional[int]:
self.start()
self._SPIDC.low()
command_as_byte = command.to_bytes(SPI_TRANSFER_LEN, sys.byteorder)
self._SPI.send(command_as_byte)
self.end()
def data(self, data=None) -> Optional[int]:
self.start()
self._SPIDC.high()
data_as_byte = data.to_bytes(SPI_TRANSFER_LEN, sys.byteorder)
self._SPI.send(data_as_byte)
self.end()
def hard_reset(self): #Hard reset display
print_debug ("LCD Hard Rst start")
self._SPICS.low()
self._SPIRST.high()
delay(50)
self._SPIRST.low()
delay(50)
self._SPIRST.high()
delay(150)
self._SPICS.high()
print_debug ("LCD Hard Rst end")
#===================================================================================================
#Classe LCD ========================================================================================
#===================================================================================================
class GC9A01():
def __init__(self):
print_debug ("LCD Init start")
self.width = 240
self.height = 240
self.spi = LCD_SPI() #Création du bus SPI
self._PINBLK = Pin('PG12', Pin.OUT_PP)#Allumage du rétro-éclairage
self._PINBLK.high()
#self._rotation = 0 % 8
self.spi.hard_reset()
print_debug ("Before delay")
delay(100)
self.spi.command(0xEF)
self.spi.command(0xEB)
self.spi.data(0x14)
self.spi.command(0xFE)
self.spi.command(0xEF)
self.spi.command(0xEB)
self.spi.data(0x14)
self.spi.command(0x84)
self.spi.data(0x40)
self.spi.command(0x85)
self.spi.data(0xFF)
self.spi.command(0x86)
self.spi.data(0xFF)
self.spi.command(0x87)
self.spi.data(0xFF)
self.spi.command(0x88)
self.spi.data(0x0A)
self.spi.command(0x89)
self.spi.data(0x21)
self.spi.command(0x8A)
self.spi.data(0x00)
self.spi.command(0x8B)
self.spi.data(0x80)
self.spi.command(0x8C)
self.spi.data(0x01)
self.spi.command(0x8D)
self.spi.data(0x01)
self.spi.command(0x8E)
self.spi.data(0xFF)
self.spi.command(0x8F)
self.spi.data(0xFF)
self.spi.command(0xB6)
self.spi.data(0x00)
self.spi.data(0x00)
self.spi.command(0x3A)
self.spi.data(0x55)
self.spi.command(0x90)
self.spi.data(0x08)
self.spi.data(0x08)
self.spi.data(0x08)
self.spi.data(0x08)
self.spi.command(0xBD)
self.spi.data(0x06)
self.spi.command(0xBC)
self.spi.data(0x00)
self.spi.command(0xFF)
self.spi.data(0x60)
self.spi.data(0x01)
self.spi.data(0x04)
self.spi.command(0xC3)
self.spi.data(0x13)
self.spi.command(0xC4)
self.spi.data(0x13)
self.spi.command(0xC9)
self.spi.data(0x22)
self.spi.command(0xBE)
self.spi.data(0x11)
self.spi.command(0xE1)
self.spi.data(0x10)
self.spi.data(0x0E)
self.spi.command(0xDF)
self.spi.data(0x21)
self.spi.data(0x0c)
self.spi.data(0x02)
self.spi.command(0xF0)
self.spi.data(0x45)
self.spi.data(0x09)
self.spi.data(0x08)
self.spi.data(0x08)
self.spi.data(0x26)
self.spi.data(0x2A)
self.spi.command(0xF1)
self.spi.data(0x43)
self.spi.data(0x70)
self.spi.data(0x72)
self.spi.data(0x36)
self.spi.data(0x37)
self.spi.data(0x6F)
self.spi.command(0xF2)
self.spi.data(0x45)
self.spi.data(0x09)
self.spi.data(0x08)
self.spi.data(0x08)
self.spi.data(0x26)
self.spi.data(0x2A)
self.spi.command(0xF3)
self.spi.data(0x43)
self.spi.data(0x70)
self.spi.data(0x72)
self.spi.data(0x36)
self.spi.data(0x37)
self.spi.data(0x6F)
self.spi.command(0xED)
self.spi.data(0x1B)
self.spi.data(0x0)
self.spi.command(0xAE)
self.spi.data(0x77)
self.spi.command(0xCD)
self.spi.data(0x63)
self.spi.command(0x70)
self.spi.data(0x07)
self.spi.data(0x07)
self.spi.data(0x04)
self.spi.data(0x0E)
self.spi.data(0x0F)
self.spi.data(0x09)
self.spi.data(0x07)
self.spi.data(0x08)
self.spi.data(0x03)
self.spi.command(0xE8)
self.spi.data(0x34)
self.spi.command(0x62)
self.spi.data(0x18)
self.spi.data(0x0D)
self.spi.data(0x71)
self.spi.data(0xED)
self.spi.data(0x70)
self.spi.data(0x70)
self.spi.data(0x18)
self.spi.data(0x0F)
self.spi.data(0x71)
self.spi.data(0xEF)
self.spi.data(0x70)
self.spi.data(0x70)
self.spi.command(0x63)
self.spi.data(0x18)
self.spi.data(0x11)
self.spi.data(0x71)
self.spi.data(0xF1)
self.spi.data(0x70)
self.spi.data(0x70)
self.spi.data(0x18)
self.spi.data(0x13)
self.spi.data(0x71)
self.spi.data(0xF3)
self.spi.data(0x70)
self.spi.data(0x70)
self.spi.command(0x64)
self.spi.data(0x28)
self.spi.data(0x29)
self.spi.data(0xF1)
self.spi.data(0x01)
self.spi.data(0xF1)
self.spi.data(0x00)
self.spi.data(0x07)
self.spi.command(0x66)
self.spi.data(0x3C)
self.spi.data(0x00)
self.spi.data(0xCD)
self.spi.data(0x67)
self.spi.data(0x45)
self.spi.data(0x45)
self.spi.data(0x10)
self.spi.data(0x00)
self.spi.data(0x00)
self.spi.data(0x00)
self.spi.command(0x67)
self.spi.data(0x00)
self.spi.data(0x3C)
self.spi.data(0x00)
self.spi.data(0x00)
self.spi.data(0x00)
self.spi.data(0x01)
self.spi.data(0x54)
self.spi.data(0x10)
self.spi.data(0x32)
self.spi.data(0x98)
self.spi.command(0x74)
self.spi.data(0x10)
self.spi.data(0x85)
self.spi.data(0x80)
self.spi.data(0x00)
self.spi.data(0x00)
self.spi.data(0x4E)
self.spi.data(0x00)
self.spi.command(0x98)
self.spi.data(0x3e)
self.spi.data(0x07)
self.spi.command(0x35)
self.spi.command(0x21)
self.spi.command(0x11)
print_debug ("LCD Init end")
#===================================================================================================
#MAIN PROGRAM ======================================================================================
#===================================================================================================
def main():
tft = GC9A01()
main()
I have 3 problems :
-
The Nicla Vision crash after the 100ms delay. With the time library or the pyb library, same result, the usb is disconnected and I have to reflash the firmware. If I comment every delay in the program, it crash even before the first print command. Why ? I don’t know.
-
Why when I speed up the SPI baudrate, the usb link crash (and I have to reflash the firmware) ? I have to deliberately choose low values to to stabilize the IDE. But it’s far from being efficient.
-
My LCD remain hopelessly black. I try with the arduino IDE and libraries (arduino GFX, Adafruit GFX) without success. I tryed the same code with and arduino Nano (but different pins) and the LCD is fully fonctional. So I don’t know. I’am on that thing for weeks.
I manage to make work a 3.3V can module MCP2515 on the 4th SPI bus, using the GPIO2 as secondary CS pin. Comparing to the arduino IDE library, it was a nightmare. Moreover with the SPI baudrate limitation. I searched for a long time. Since I buy this board, I got only troubles and few post to help. I am using the OpenMV IDE and contrary to the Arduino IDE, I can’t rely on in-built modules.
So if someone with more knowledge than me about delay and SPI on the Arduino Nicla could help me, he will receive my eternal gratefull.
Thank for everyone who will take time to read my long post. And even more to those who can help me below.