peterhinch / micropython-nano-gui

A lightweight MicroPython GUI library for display drivers based on framebuf class
MIT License
506 stars 88 forks source link

SSD1351 Not working on ESP32 #2

Closed GraphicHealer closed 4 years ago

GraphicHealer commented 4 years ago

Hello, I have tried to get this to work several times, but for some reason my display does not light up. The ssd1351_16.py runs, and it says all of the print lines as if it is running, but it doesnt show anything on screen. Any ideas as to why this is not working? Thanks.

Edit: I also just tried the ssd1351_generic.py and it still does not show anything.

peterhinch commented 4 years ago

I'll need more information than that if I'm to help, including your electrical connections.

The first step is to adapt one of the simple test scripts in the ssd1351 directory to match your connections. Then run it. If that fails, show me any trace information that you see at the REPL.

GraphicHealer commented 4 years ago

I have the pins connected as so: DC = 17 CS = 5 RST = 16 CLK = 18 MOSI = 23

I did change to SPI(2) in the test code.

It doesnt give errors. It acts as if everything is running smoothly on the board, but there is nothing on the display. I did have to change the pin mode to OUT, not OUT_PP as OUT_PP is not an option on the esp32. Aparently though, OUT on the esp32 is OUT_PP.

BTW, my display is the 128x128 and i used the script for that one. I also have switched the pins to SPI(1) and it still does nothing

peterhinch commented 4 years ago

OUT on the esp32 is OUT_PP

Yes.

On boards with SPIRAM, pins 16 and 17 may be used to access this (e.g. ESP32-WROVER-KIT). Could there be a conflict here?

GraphicHealer commented 4 years ago

Hmm. the strange part is another ssd1351 driver works flawlessly on my board. IDK if the author specifically diabled the SPIRAM, or what. Ill try all new pins. See how it goes.

Other driver: https://github.com/rdagger/micropython-ssd1351

GraphicHealer commented 4 years ago

I tried SPI(1) and the pins 25, 26, and 27 for dc, cs, and rst respectively. The screen is still just blank with the 128 test.

GraphicHealer commented 4 years ago

I also have re-flashed the BIN file and tried from a clean slate. It still runs the code fine, just no display output. No errors are even thrown.

peterhinch commented 4 years ago

I'm at a loss here as to how to diagnose this. [EDIT] The following "works" with the Adafruit board, but not at all well:

import machine
from ssd1351_generic import SSD1351 as SSD

# Initialise hardware
def setup():
    pdc = machine.Pin(25, machine.Pin.OUT, value=0)
    pcs = machine.Pin(26, machine.Pin.OUT, value=1)
    prst = machine.Pin(27, machine.Pin.OUT, value=1)
    spi = machine.SPI(-1, sck=machine.Pin(18), mosi=machine.Pin(23), miso=machine.Pin(22))
    ssd = SSD(spi, pcs, pdc, prst)  # Create a display instance
    return ssd

ssd = setup()
ssd.fill(0)
ssd.line(0, 0, 127, 127, ssd.rgb(0, 255, 0))
ssd.rect(0, 0, 15, 15, ssd.rgb(255, 0, 0))
ssd.show()

Soft SPI produces a visible result, whereas as you found, hard SPI shows nothing. But its operation is inconsistent, with repeated runs producing different incorrect outcomes. There is presumably a hardware or timing issue associated with the ESP32.

It may be a while before I get a chance to properly investigate this.

GraphicHealer commented 4 years ago

Is that script using soft SPI? If not, How do I implement that into your code? Thanks fro the help by the way. Let me know when you get hardware SPI fixed. Thanks.

edit: Would changing baud-rate help it work? EX: SPI(2, baudrate=14500000, sck=Pin(18), mosi=Pin(23))

peterhinch commented 4 years ago

Progress!

Please change this line to read

self.spi.init(baudrate=self.rate, polarity=0, phase=0)

On my hardware the following works with that amended driver and your pin connections. It uses hard SPI.

import machine
from ssd1351_generic import SSD1351 as SSD

# Initialise hardware
def setup():
    pdc = machine.Pin(25, machine.Pin.OUT, value=0)
    pcs = machine.Pin(26, machine.Pin.OUT, value=1)
    prst = machine.Pin(27, machine.Pin.OUT, value=1)
    spi = machine.SPI(1, sck=machine.Pin(18), mosi=machine.Pin(23), miso=machine.Pin(22))
    ssd = SSD(spi, pcs, pdc, prst)  # Create a display instance
    return ssd

ssd = setup()
ssd.fill(0)
ssd.line(0, 0, 127, 127, ssd.rgb(0, 255, 0))
ssd.rect(0, 0, 15, 15, ssd.rgb(255, 0, 0))
ssd.show()

Justification

The SSD1351 datasheet indicates that polarity=1, phase=1 or polarity=0, phase=0 are both valid. I used the former extensively with a Pyboard host. I must have had a reason for choosing 1, but I can't recall it.

I'll have to investigate further before changing the master. I will check to see If the ESP32 firmware has a problem; this seems the most likely reason for the issue.

Re your earlier questions

Baudrate had no effect in my testing. Soft SPI is selected simply by using SPI no. -1.

Suggestion

Hard SPI should be faster so unless you have continuing problems I suggest you just change that one line in the driver, and run my latest script as above.

Please let me know if you have success with this change.

peterhinch commented 4 years ago

I have pushed an update which changes bus initialisation on ESP32 only. I'm none the wiser as to why this is necessary: the waveforms look perfect. I suspect a rare corruption of the SPI bus signals in (1,1) mode, but it's not obvious how to produce evidence for the maintainers.

Tested with the above script, also with nanogui samples adapted for ESP32 pin numbers.

Thank you for pointing out this bug.

GraphicHealer commented 4 years ago

Ha! I thought it didn't work at first, because you switched the pins to SPI(2) on SPI(1). Changed the pins back to CLK on 14 and MOSI on 13. It works flawlessly now. Thank you so much!

EDIT: Didn't see you had updated. Thanks!