adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.11k stars 1.22k forks source link

displayio: the display does not survive a VM restart on SAMD21 #6277

Closed deshipu closed 2 years ago

deshipu commented 2 years ago

CircuitPython version

Adafruit CircuitPython 7.3.0-alpha.0-22-g102ee716a-dirty on 2022-04-12; PewPew LCD with samd21e18

Code/REPL

import board
import terminalio
import displayio
from adafruit_display_text import label
from adafruit_st7789 import ST7789
import busio

# Release any resources currently in use for the displays
displayio.release_displays()

spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI)
tft_cs = board.D5
tft_dc = board.D9

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=board.D6
)

display = ST7789(display_bus, width=240, height=240, rowstart=80)

# Make the display context
splash = displayio.Group()
display.show(splash)

color_bitmap = displayio.Bitmap(24, 24, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x00FF00  # Bright Green

bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)

# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(20, 20, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0xAA0088  # Purple
inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=20, y=20)
splash.append(inner_sprite)

# Draw a label
text_group = displayio.Group(scale=2, x=50, y=120)
text = "Hello World!"
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFF00)
text_group.append(text_area)  # Subgroup for text scaling
splash.append(text_group)

Behavior

The display keeps displaying two squares and text even after the code finishes running. It should instead display the REPL with the "Code done running." message.

IMG_20220412_214723

Same happens when the code is interrupted with ctrl+c — instead of REPL, the display shows the last thing the program was displaying.

Description

The reverse happens if I copy-paste the display initialization code in the REPL — the display works until ctrl+c is pressed.

Additional information

If the display is initialized in board.c as part of the startup, then it initializes properly, but never displays anything.

deshipu commented 2 years ago

With more testing, I noticed that sometimes, randomly, I can get a line or two of the traceback, before the display freezes, so there is some kind of race condition in there perhaps?

deshipu commented 2 years ago

A much easier reproducer: the HalloWing M0 Express display no longer works with recent versions of CircuitPython.

deshipu commented 2 years ago

The last version that works is adafruit-circuitpython-hallowing_m0_express-en_US-7.0.0-alpha.6.uf2, the first version that is broken is adafruit-circuitpython-hallowing_m0_express-en_US-7.0.0-beta.0.uf2.

deshipu commented 2 years ago

Further testing leads me to believe that it's commit f0859ac954e71e00e298843dc7f9f9c09a9bf570 that broke this.

deshipu commented 2 years ago

I have tried to experiment with this, but I really don't know what is happening. Perhaps the clock that the SPI peripheral uses gets shut down? The code itself doesn't refer to anything directly related to displayio. I give up.

dhalbert commented 2 years ago

Further testing leads me to believe that it's commit f0859ac that broke this.

Confirmed via bisect.