#I don't have experience with that

1 messages ยท Page 1 of 1 (latest)

plain berry
#

after the code above I tried several examples from the displayIO guide, eg. like:

#

# Create a bitmap with two colors
bitmap = displayio.Bitmap(display.width, display.height, 2)

# Create a two color palette
palette = displayio.Palette(2)
palette[0] = 0x000000
palette[1] = 0xffffff

# Create a TileGrid using the Bitmap and Palette
tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)

# Create a Group
group = displayio.Group()

# Add the TileGrid to the Group
group.append(tile_grid)

# Add the Group to the Display
display.root_group = group

# Draw a pixel
bitmap[80, 50] = 1

# Draw even more pixels
for x in range(150, 170):
    for y in range(100, 110):
        bitmap[x, y] = 1


# Loop forever so you can enjoy your image
while True:
    pass ```
#

but dark blank black screen ๐Ÿ˜ฆ

cedar terrace
#

What build of CircuitPython have you flashed onto the microcontroller?

plain berry
#

that did work, but I want to use the wifi module from circuitpython. so shifted to CP.

#

Adafruit CircuitPython 9.0.0 on 2024-03-19; ESP32-S3-DevKitC-1-N8R2 with ESP32S3

cedar terrace
#

I'm assuming the 9 there is why you chose data0 = board.IO9, in your init code

plain berry
#

not sure if it has to do with the init sequence. per the s3lcd git the init sequence looks a bit different. But not sure how to map the tuples from that example to the format what is used in DJDevon3s driver

cedar terrace
#

Since that device appears to use a list that is not in that order I think you would need to use data_pins not data0

plain berry
#

yeah that's what I understood, data0 is the first pin and the rest is implied.. and i fully missed that data_pins attribute ๐Ÿ˜ฆ

#

because I have the exact mapping.. gonna try that..

#

unfortunately ๐Ÿ˜ฆ

#

same darkness keeps looking at me

cedar terrace
#

can you post your new current code here

plain berry
#
import paralleldisplaybus
import board
import displayio
import st7796s



# release the display. Must always be called.
displayio.release_displays()

# Initialize the 8bit but 
display_bus = paralleldisplaybus.ParallelBus(
#     data0 = board.IO9,
    data_pins = [board.IO9, board.IO46, board.IO3, board.IO8, board.IO18, board.IO17, board.IO16, board.IO15],
    command = board.IO0,
    chip_select = board.IO6,
    write= board.IO47,
    reset = board.IO4,
    frequency = 20000000 
    )


display = st7796s.ST7796S(display_bus, width=320, height=480, invert=True)


# Create a bitmap with two colors
bitmap = displayio.Bitmap(display.width, display.height, 2)

# Create a two color palette
palette = displayio.Palette(2)
palette[0] = 0x000000
palette[1] = 0xffffff

# Create a TileGrid using the Bitmap and Palette
tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)

# Create a Group
group = displayio.Group()

# Add the TileGrid to the Group
group.append(tile_grid)

# Add the Group to the Display
display.root_group = group

# Draw a pixel
bitmap[80, 50] = 1

# Draw even more pixels
for x in range(150, 170):
    for y in range(100, 110):
        bitmap[x, y] = 1


# Loop forever so you can enjoy your image
while True:
    pass
#

and this is the adjusted driver: ```python

SPDX-FileCopyrightText: 2023 DJDevon3 with OpenAI ChatGPT 3.5

SPDX-License-Identifier: MIT

Circuit Python Driver for ST7796S display

https://help.openai.com/en/articles/6825453-chatgpt-release-notes

https://chat.openai.com/share/22db9572-8ad6-4dfc-8b97-43f60afc2ef3

try:
# used for typing only
from typing import Any
except ImportError:
pass

from busdisplay import BusDisplay
from paralleldisplaybus import ParallelBus

Landscape Mode

_INIT_SEQUENCE = bytearray(
b"\x01\x80\x01" # Software reset and Delay 150ms
b"\x11\x80\x01" # Sleep out and Delay 500ms
b"\x3A\x81\x55\x0A" # Set color mode to 16 bits per pixel and Delay 10ms
b"\x29\x80\x01" # Display on and Delay 500ms
)

pylint: disable=too-few-public-methods

class ST7796S(BusDisplay):
"""
ST7796S display driver

:param FourWire bus: bus that the display is connected to
:param bool portrait: (Optional) Portrait or Landscape mode (default=False)
:param bool invert: (Optional) Invert the colors (default=False)
"""

def __init__(
    self, bus: ParallelBus, *, portrait: bool = False, invert: bool = False, **kwargs: Any
):
    init_sequence = _INIT_SEQUENCE
    if portrait:
        init_sequence += (
            b"\x36\x01\x48"  # _MADCTL for portrait mode
        )
    else:
        init_sequence += (
            b"\x36\x01\x28"  # _MADCTL for landscape mode
        )
    if invert:
        init_sequence += b"\x21\x00"  # _INVON
    super().__init__(bus, init_sequence, **kwargs)
carmine crescent
#

I tried to get the parallelbus to work with a display I had, but I couldn't. I think there is something in it that is specific to the display for which it was originally written.

#

but I never had the time to actually look at the signals with the logic analyzer

plain berry
#

awesome you tried at least... got me one step closer... (fixing the pins)...

cedar terrace
#

I don't know how chip_select works with ParallelBus but I'm not sure that this would be correct: chip_select = board.IO6, in the data sheet that you linked GPIO 6 is not listed under the LCD section of pins. It looks to be part of the touch screen I2C bus maybe?

#

I noticed pin 48 is under the LCD section, and isn't used by your code currently. don't know what "Frame Sync" means really though, perhaps that is unneeded for CircuitPython

carmine crescent
#

it's an output pin that goes low at the end of every frame

#

it's not used in cp

plain berry
#

true i have been searching for the CS myself as well, since the datasheet did not provide it. So the s3lcd MP example referenced above (which did work for me when I loaded MP on the device), had the IO6 pin for CS

carmine crescent
#

is cs obligatory?

cedar terrace
#

Ah, right I didn't notice it in the micropython example. That is the extent of my ideas I think.

plain berry
#

yeah cs is mandatory unfortunately

carmine crescent
plain berry
#

yeah.. i can swicth with IO45

#

i see in the s3lcd MP library the machine.freq is set to 240_000_000 . .. don't know if this is relevant and how to do that in CP... (not the bus freq which is configured at 20_000_000)

#

also I remember reading somewhere that for displayio the AdaFruit boards already have a pin high/low by default (but honestly don't remember this was related to my search for an answer)

carmine crescent
#

if you get dark screen, then it's failing to send the init sequence properly

plain berry
#

ok so it might be the wrong init sequence then

carmine crescent
#

where did you get it from?

#

it could be wrong init sequence, one of the control pins connected incorrectly, or the data pins connected in wrong order

#

or it could be something completely different, like power

plain berry
#

the init sequence as per the s3lcd mp library looks like this: ```def config(rotation=0, options=0):
"""Configure the display and return an ESPLCD instance."""

custom_init = (
    (b"\x01", 120),
    (b"\x11", 120),
    (b"\xF0\xC3",),
    (b"\xF0\x96",),
    (b"\x36\x48",),
    (b"\x3A\x55",),
    (b"\xB4\x01",),
    (b"\xB6\x80\x02\x3B",),
    (b"\xE8\x40\x8A\x00\x00\x29\x19\xA5\x33",),
    (b"\xC1\x06",),
    (b"\xC2\xA7",),
    (b"\xC5\x18", 120),
    (b"\xE0\xF0\x09\x0B\x06\x04\x15\x2F\x54\x42\x3C\x17\x14\x18\x1B",),
    (b"\xE1\xE0\x09\x0B\x06\x04\x03\x2B\x43\x42\x3B\x16\x14\x17\x1B", 120),
    (b"\xF0\x3C",),
    (b"\xF0\x69",),
    (b"\x29",),
)```
#

which is in a bit of a different format

#

so I thought that by converting it to ```

_INIT_SEQUENCE2 = bytearray(
b"\x01\x78"
b"\x11\x78"
b"\xF0\xC3"
b"\xF0\x96"
b"\x36\x48"
b"\x3A\x55"
b"\xB4\x01"
b"\xB6\x80\x02\x3B"
b"\xE8\x40\x8A\x00\x00\x29\x19\xA5\x33"
b"\xC1\x06"
b"\xC2\xA7"
b"\xC5\x18\x78"
b"\xE0\xF0\x09\x0B\x06\x04\x15\x2F\x54\x42\x3C\x17\x14\x18\x1B"
b"\xE1\xE0\x09\x0B\x06\x04\x03\x2B\x43\x42\x3B\x16\x14\x17\x1B\x78"
b"\xF0\x3C"
b"\xF0\x69"
b"\x29"
)

#

might work ... to no avail ๐Ÿ˜ฆ

carmine crescent
#

how did you come up with b"\x01\x78"?

plain berry
#

\x78 = 120

carmine crescent
#

that's not how this works

plain berry
#

or am i misinterpreting the format difference?

#

ah...

carmine crescent
#

in the CP format, the first byte is the command, the second byte says how many additional bytes there are and whether there is a delay, then the additional bytes and the delay go

#

so for example b"\x3A\x81\x55\x0A" means "send command 3A followed by one byte and a delay, the byte is 55 aand the delay is 0A"

#

those commends are wrong, by the way b"\x01\x80\x01" actually says "send 01 and wait 1ms"

#

not 150ms

plain berry
#

@buoyant crypt in the main conversation has converted this init sequence to CP style ๐Ÿ˜‰ gonna check it now

buoyant crypt
#

i make no guarantees

carmine crescent
#

in theory you should only need the sleep out and power on commands to display something, but I wonder if the problem is that they have too short delays

plain berry
#

stupid question, but do I have to define my pins to be output like for the backlight?

buoyant crypt
#

you can, but it's not required.

#

usually.. but maybe in your case it does..

#

i'm thinking of my display where backlight on is default

carmine crescent
#

the parallelbus sets the pins to the right direction

#

in fact, if you try to set them yourself, you will get a pin in use error

plain berry
#

ok... time to hit the bed here... thanks for all support everyone... will go and research further later this week...

#

awesome community to help out.

#

one final question, which might have disappeared in the flood of messages:

#

i see in the s3lcd MP library the machine.freq is set to 240_000_000 . .. don't know if this is relevant and how to do that in CP... (not the bus freq which is configured at 20_000_000)

buoyant crypt
#

That's the frequency of the esp32.. no need to do anything with that.

carmine crescent
#

it shouldn't matter, iirc you can change it with microcontroller.cpu.frequency

plain berry
#

tnx...

carmine crescent
#

but it doesn't affect the signal being sent to the screen

magic dust
#

The reason that initi sequence is so short is because I kept having circuit python double reset. Every file save it auto-reloads twice, sometimes 3. Thought it might be due to too long of display timings so I started cutting things out... which of course made things worse. That init sequence is as bare bones as you can get for the ST7796, I do not recommend others run it with other displays. Some parts of the sequence are specific to the ST7796S which is why you MUST read the datasheet for your display and pick out the hex settings relevant for the way you want to configure your display.

#

I still don't think my ST7796S driver works 100% as intended in every situation. It does work well for different displayio rotations which covers 99% of use case scenarios.

#

There's a difference between a display driver rotation and displayio rotation. They're 2 completely different things. The display driver sets the native rotation. Then displayio rotation 0 works from the rotation set by the driver. Throw in a touch screen with touch rotation and you've got a recipe for trying to track 8 different rotation scenarios.

#

display = st7796s.ST7796S(display_bus, width=320, height=480, invert=True) because the width is less than the height this should be using portrait=True.

#

Invert is for color inversion, you'll know if your color mode is inverted when displaying an image all colors are backwards and looks like something Charles Manson would paint. by default most TFT's have a black background with white text. if you have a white background with black text you'll know it's inverted.

#

Also with a bad init sequence the display might slowly turn white which has nothing to do with inversion mode and is more like the displays way of saying "error in init sequence".

#

I got the ST7796 to work in 16-bit mode but everything was squished and was in RGB888 mode. I'll never use it that way but was neat to see these types of TFT's are capable of much more than circuit python config is using it for.

buoyant crypt
#

@plain berry I just realized something.. Do you have the WT32-SCO1 with the ESP32 or the WT32-SCO1 PLUS with the ESP32S3?

#

if it's the plain ESP32, the answer is: parallel display currently doesn't work with it, as far as I can tell. It works with ESP32S3 MCUs, but not original ESP32 units.

#

(in Circuit Python, that is. Clearly it works in Arduino / OpenHASP, etc)

#

I spent the last two weeks tearing the whole Parallel Display Bus system apart trying to figure out why my ESP32-S2432S022 won't work. It has a similar setup with an ili9341 8 bit parallel display and original ESP32 MCU. When I hooked the same model display to a nodemcu-32 (plain esp32 dev board) it did the same thing.. Wouldn't initialize, just got nothing or garbage on screen. When I hooked that same screen to an ESP32S3 changing nothing in code, it just started working. There's something up with the differences between the two and how the ESP-IDF toolchain works, I think. Was talking to tannewt about it and he had the suggestion that maybe when the esp-idf toolchain used in CircuitPython builds is upgraded to 5.2.1, it might just work.