Skip to content

adafruit_sdcard causes device to lock up on versions newer than 4.1.2 when used with OnDiskBitmap #3309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
FoamyGuy opened this issue Aug 21, 2020 · 2 comments · Fixed by #3449

Comments

@FoamyGuy
Copy link
Collaborator

I have this code running on a PyPortal:

import board
from adafruit_pyportal import PyPortal

# Set a data source URL
IMAGE_URL = "http://192.168.1.109:8000/image_compressed2.bmp"
TEXT_URL = "http://192.168.1.109:8000/test.txt"

# Create the PyPortal object
pyportal = PyPortal(
#    url=TEXT_URL,
#    image_url_path=IMAGE_URL,
    status_neopixel=board.NEOPIXEL,
    debug=True,
#    convert_image=False
)

pyportal.set_background(0xFF00FF)

# Go get that data
# print("Fetching")
# data = pyportal.fetch()

pyportal.set_background("/sd/cache.bmp")
print("after")
while True:
    pass

It was originally fetching the image to test an unrelated PR. Now it is just using pyportal.set_background("/sd/cache.bmp") to try to set the background to an image stored on the sdcard.

When this code runs the PyPortal gets into a "stuck" state where CIRCUITPY becomes unresponsive and disappears. The serial console becomes unresponsive. If I press the reset button the device will reboot as normal but when the set_background() call executes it will get stuck again. If I press the reset button twice I do successfully get t bootloader mode.

I can see 1 pixel (I think its 1) getting drawn at the top of the screen from my bmp image. But nothing else gets drawn on the screen and then the devices gets into the "stuck" state mentioned above.

I have tested this on some older versions and have realized that back on Circuit Python version 4.1.2 this code works correctly. But 5.0.0 and anything newer (up to latest in S3) the code gets "stuck" as noted above.

I'm guessing that something in the PyPortal library may need to be updated. But also perhaps there is a way in the core to prevent this from getting into the "stuck" state?

@cjsieh
Copy link

cjsieh commented Aug 23, 2020

This also fails on the PyGamer . Issue seems to be related to adafruit_sdcard . If sdcardio is used instead it works fine.

odb-test.zip
This example can use either adafruit_sdcard or sdcardio . Just comment and un-comment as needed.

As sdcardio works and is faster it would be a better default choice for PyPortal defaults. Working on a PR now.

@FoamyGuy
Copy link
Collaborator Author

Nice find @cjsieh! I was able to confirm your reproducer example and fix within it.

I'm including a slightly modified version of the code here for convenience and discussion:

import board
import displayio
import busio
import storage
import time

print("waiting 10 sec")
time.sleep(10)
print("continuing")

# Use the board's primary SPI bus
spi = board.SPI()

# works on pyportal and pygamer
import sdcardio
cs = board.SD_CS
sdcard = sdcardio.SDCard(spi, cs)
print("enabled sdcard via sdcardio")

#OR

# Fails on pyportal and pygamer
#import adafruit_sdcard
#import digitalio
#cs = digitalio.DigitalInOut(board.SD_CS)
#sdcard = adafruit_sdcard.SDCard(spi, cs)
#print("enabled sdcard via _sdcard")


vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
print("mounted sdcard on /sd")

board.DISPLAY.auto_brightness = False
board.DISPLAY.brightness = 0.40
splash = displayio.Group()
board.DISPLAY.show(splash)

with open("/sd/cache.bmp", "rb") as f:
    print("opened /sd/cache.bmp")
    odb = displayio.OnDiskBitmap(f)
    face = displayio.TileGrid(odb, pixel_shader=displayio.ColorConverter())
    splash.append(face)
    # Wait for the image to load.
    board.DISPLAY.refresh(target_frames_per_second=60)
    print("background bitmap loaded")

    # Wait forever
    while True:
        pass

I added 10 seconds of sleep at the beginning to give ample time to connect to REPL and KeyboardInterupt before the lockup when it's using the code that causes it.

@FoamyGuy FoamyGuy changed the title PyPortal.set_background() gets device stuck after version 4.1.2 adafruit_sdcard causes device to lock up on versions newer than 4.1.2 when used with OnDiskBitmap Aug 23, 2020
jepler added a commit to jepler/circuitpython that referenced this issue Oct 2, 2020
An RGBMatrix has no bus and no bus_free method.  It is always possible
to refresh the display.

This was not a problem before, but the fix I suggested (adafruit#3449) added
a call to core_bus_free when a FramebufferDisplay was being refreshed.
This was not caught during testing.

This is a band-aid fix and it brings to light a second problem in which
a SharpDisplay + FrameBuffer will not have a 'bus' object, and yet does
operate using a shared SPI bus.  This kind of display will need a
"bus-free" like function to be added, or it can have problems like
adafruit#3309.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants