Skip to content

usb_host_mass_storage_simpletest.py take for ever, block a cp and kill tio #2

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

Open
dglaude opened this issue Aug 15, 2023 · 4 comments

Comments

@dglaude
Copy link

dglaude commented Aug 15, 2023

Not sure what to report but here is what I did and observed.

I deployed 8.2.0-75-gc75640eb0 on a Feather RP2040 USB Host.
Then I added in /lib the library from:

At that point I inserted a USB key and I started to get output, and a directory listing of the root of the USB key.
The USB key continued to blink, but there was no further output.

So at that point I took another terminal window and tried to copy over the simple_test from USB_Host_Descriptors on the Feather.
But that copy was stuck, and the prompt not coming back. The USB key was still blinking, then tio told me I was disconnected from the REPL. And in the other window, my cp command ended (but likely not successfully).

At that point the USB key was still blinking, but the CP board was not visible from discotool anymore.

I just tested a second time with a cp CODE_OF_CONDUCT.md /media/dglaude/CIRCUITPY/ and same scenario cp does not end and tio disconnect.

I don't have many USB key (mass storage) to try, but I will try again to see if it content specific.

Some output:

>>> 
>>> 
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
searching for devices
pid 0x3e00
vid 0x13fe
man         
product USB DISK 2.0
serial 0701C20FB2DEE160
mounting
['.disk', 'boot', 'boot.catalog', 'casper', 'dists', 'EFI', 'install', 'md5sum.txt', 'pool', 'ubuntu', 'autorun.inf', 'autorun.ico', 'System Volume Information']

[tio 14:49:06] Disconnected
/media/dglaude/CIRCUITPY/:
boot_out.txt
code.py
lib
settings.toml
usb_host_mass_storage_simpletest.py

/media/dglaude/CIRCUITPY/lib:
adafruit_usb_host_descriptors.py
adafruit_usb_host_mass_storage.py
@tyeth
Copy link

tyeth commented Mar 10, 2024

Just tested this, only had one usb stick, it sees it, gets stats, but can't mount it (block device doesn't exist).

It also stalls (rather than errors) attempting to mount it if you change code.py and it therefore reruns the init code as part of re-running code.py - think that usb stick is really slow to mount/work.

I then tried some inception level stuff and connected a T-DisplayS3 running circuitpython. It listed the files happily, and because I didn't notice it had stalled I assumed it had written hello.txt too. I then rebooted(or was it ctrl+d) rp2040 to see if the hello.txt was listed, but then failed to do something (presumable read hello.txt) with USB Pipe Error / Memory Error.

Later tried a USB3 SD card reader, chucked on 1 bmp and a boot_log.txt and changed the example to read+print that boot_log.txt first, which works, then it stalls when trying to write file.

Tagging @tannewt for an enjoyable test bed when playing with USB Host stuff as he said he might be looking at it this week.
I'm running the simple test example with a bit of extra logging on the RP2040 Feather USB Host plugged into the 3.5" capacitive touch screen. SD card present if that matters.

Leaving the write to attempt to complete ended up with the device disconnecting after a fewminutes and it reconnects as a broken usb device on windows (battery connected to feather to avoid low power over usb).

Logs

Logs:

---- Closed serial port COM17 due to disconnection from the machine ----
---- Reopened serial port COM17 ----
searching for devices
pid 0x9917
vid 0x26bd
man         
product USB DISK 3.0
serial 070148EEB7289D25
mounting
Traceback (most recent call last):
  File "code.py", line 40, in <module>
OSError: [Errno 19] No such device

Code done running.
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.

Press any key to enter the REPL. Use CTRL-D to reload.
---- Closed serial port COM17 due to disconnection from the machine ----
---- Reopened serial port COM17 ----
---- Closed serial port COM17 due to disconnection from the machine ----
---- Reopened serial port COM17 ----
Hard fault: memory access or instruction error.
Please file an issue with your program at github.com/adafruit/circuitpython/issues.
Press reset to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
---- Closed serial port COM17 due to disconnection from the machine ----
---- Reopened serial port COM17 ----
searching for devices
pid 0x813f
vid 0x303a
man LILYGO
product T-Display S3
serial 4F21AFFC1B8C
mounting
['.fseventsd', '.metadata_never_index', '.Trashes', '.Trash-1000', 'sd', 'lib', 'System Volume Information', 'useful.py', '.vscode', '._code copy.py', 'boot.json', 'boot.py', 'boot_out.txt', 'client_secret_847729985298-cdf2sn4detftamitlh7m0710rb20lonq.apps.googleusercontent.com.json', 'code.py', 'code_2024_03_09_itertools.py', 'code_back.py', 'code_new.py', 'code_OLD.py', 'cp_9.bmp', 'cp_9_320x170.bmp', 'Inter-Thin-30.bdf', 'safemode.json', 'safemode.py', 'settings.toml', 'splash.bmp']
---- Closed serial port COM17 due to disconnection from the machine ----
---- Reopened serial port COM17 ----
🐍code.py | 9.0.0-rc.0searching for devices
pid 0x813f
vid 0x303a
man LILYGO
product T-Display S3
serial 4F21AFFC1B8C
mounting
['.fseventsd', '.metadata_never_index', '.Trashes', '.Trash-1000', 'sd', 'lib', 'System Volume Information', 'useful.py', '.vscode', '._code copy.py', 'boot.json', 'boot.py', 'boot_out.txt', 'client_secret_847729985298-cdf2sn4detftamitlh7m0710rb20lonq.apps.googleusercontent.com.json', 'code.py', 'code_2024_03_09_itertools.py', 'code_back.py', 'code_new.py', 'code_OLD.py', 'cp_9.bmp', 'cp_9_320x170.bmp', 'Inter-Thin-30.bdf', 'safemode.json', 'safemode.py', 'settings.toml', 'splash.bmp']
Traceback (most recent call last):
  File "code.py", line 51, in <module>
  File "/lib/adafruit_usb_host_mass_storage.py", line 226, in writeblocks
  File "/lib/adafruit_usb_host_mass_storage.py", line 143, in _scsi_command
usb.core.USBError: Pipe error

Code done running.
MemoryError: 
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.

Press any key to enter the REPL. Use CTRL-D to reload.

Code.py

# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2023 Scott Shawcroft for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense

import time
import os
import storage
import usb.core

import adafruit_usb_host_mass_storage
def os_Exists(path):
    try: 
        return os.stat(path) != None; 
    except: 
        return False

device = None
while device is None:
    print("searching for devices")
    for device in usb.core.find(find_all=True):
        print("pid", hex(device.idProduct))
        print("vid", hex(device.idVendor))
        print("man", device.manufacturer)
        print("product", device.product)
        print("serial", device.serial_number)
        break
    if not device:
        time.sleep(5)

print("mounting")
msc = adafruit_usb_host_mass_storage.USBMassStorage(device,1)
vfs = storage.VfsFat(msc)
if not os_Exists('/usb_drive'):
    try:
        os.mkdir('/usb_drive')
    except Exception as e:
        print("Error creating directory: ", e)
        raise Exception("***** ====> Drive NOT WRITABLE! <====\nManually create the usb_drive folder on the CIRCUITPY drive")
storage.mount(vfs, "/usb_drive")

l = os.listdir("/usb_drive")
print(l)
if "boot_out.txt" in l:
    print("boot_out.txt:")
    with open("/usb_drive/boot_out.txt", "r") as f:
        print("\n".join(f.readlines()))
        print("Read boot_out.txt successfully")
print("Done reading boot_out.txt")

if "hello.txt" in l:
    print("hello.txt:")
    with open("/usb_drive/hello.txt", "r") as f:
        print(f.read())
        print("Read hello.txt successfully")

print("Writing to /usb_drive/hello.txt")
with open("/usb_drive/hello.txt", "w") as f:
    f.write("Hello from the USB host device!")
    print("Wrote to hello.txt")

print("Done all.")

image

@tyeth
Copy link

tyeth commented Mar 10, 2024

Minor update, although it could read boot_out.txt, when testing reading a bitmap (601k) it never finished, and eventually rebooted as a broken usb device

BMP displaying code (rp2040 usb host feather + 3.5 cap touch screen with sd):

# SPDX-FileCopyrightText: 2023 Tyeth Gundry for Adafruit Industries
# SPDX-License-Identifier: MIT

"""
This test will initialize the display using displayio and display
a bitmap image. The image advances when the touch screen is touched.
Flash storage, SD card, and USB mass storage are all supported (*.BMP).

Pinouts are for the 3.5" TFT FeatherWing V2
"""
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2023 Scott Shawcroft for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense

import time
import board
import digitalio
import displayio
import adafruit_hx8357
import adafruit_ft5336
import os
import storage
import adafruit_sdcard
import usb.core
import adafruit_usb_host_mass_storage

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

# Use Hardware SPI
spi = board.SPI()

sd_cs = board.D5
tft_cs = board.D9
tft_dc = board.D10

display_width = 480
display_height = 320

display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs )#, baudrate=60_000_000)
display = adafruit_hx8357.HX8357(display_bus, width=display_width, height=display_height)

i2c = board.STEMMA_I2C()

irq_dio = None
# tsc = adafruit_tsc2007.TSC2007(i2c, irq=irq_dio)
touch = adafruit_ft5336.Adafruit_FT5336(i2c) # 0x38 is the default address for the FT5336

groups = []
images = []
def list_files(path='/'):
    global images
    for filename in os.listdir(path):
        if filename.lower().endswith('.bmp') and not filename.startswith('.'):
            images.append((path if path.endswith('/') else path+"/" )+filename)

def os_Exists(path):
    try: 
        return os.stat(path) != None; 
    except: 
        return False
    
def mkdir_or_die(path):
    if not os_Exists('/usb_drive'):
        try:
            os.mkdir('/usb_drive')
        except Exception as e:
            print("Error creating directory: ", e)
            raise Exception("***** ====> Drive NOT WRITABLE! <====\nManually create the %s folder on the CIRCUITPY drive" % path)

#attempt to mount sd card

def mountSD():
    try:
        print("Attempting to mount SD card")
        sdcs = digitalio.DigitalInOut(sd_cs)
        sd = adafruit_sdcard.SDCard(spi, sdcs)
        vfs = storage.VfsFat(sd)
        if not os_Exists('/sd'):
            os.mkdir('/sd')
        storage.mount(vfs, "/sd")
        print("SD card mounted")
        return True
    except Exception as e:
        print("Error mounting SD card: ", e)
        return False
mountSD()

if os_Exists('/sd'):
    print("SD Directory exists")
    list_files('/sd')

# mount usb
def mountUSB():
    try:
        device = None
        timeout_ms = time.monotonic() + 10
        while device is None and time.monotonic() < timeout_ms:
            print("searching for devices")
            for device in usb.core.find(find_all=True):
                print("pid", hex(device.idProduct))
                print("vid", hex(device.idVendor))
                print("man", device.manufacturer)
                print("product", device.product)
                print("serial", device.serial_number)
                break
            if not device:
                time.sleep(0.5)

        if device is None:
            print("No USB device found")
            return False
        print("mounting USB")
        msc = adafruit_usb_host_mass_storage.USBMassStorage(device,1)
        vfs = storage.VfsFat(msc)
        mkdir_or_die("/usb_drive")
        storage.mount(vfs, "/usb_drive")
        print("USB mounted")
        return True
    except Exception as e:
        print("Error mounting USB: ", e)
        return False
if mountUSB():    
    list_files('/usb_drive')


# flash storage
list_files('/')
print(images)

for i in range(len(images)):
    splash = displayio.Group()
    bitmap = displayio.OnDiskBitmap(images[i])
    tile_grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader)
    splash.append(tile_grid)
    groups.append(splash)

index = 0
touch_state = False

display.root_group = groups[index]
print("displaying image %s" % images[index])

point={"x":0,"y":0,"finger":0}
while True:
    if touch.touched and not touch_state:
        try:
            for i,tpoint in enumerate(touch.points):
                print(tpoint)
                point["x"] = tpoint[0]
                point["y"] = tpoint[1]
                point["finger"] = tpoint[2]
                print("Touchpoint #%d: (%d, %d, %d)" % (i, point["x"], point["y"], point["finger"]))
                # left side of the screen
                if point["y"] < 2000:
                    index = (index - 1) % len(images)
                    display.root_group = groups[index]
                # right side of the screen
                else:
                    index = (index + 1) % len(images)
                    display.root_group = groups[index]
                print("displaying image %s" % images[index])
        except RuntimeError:
            pass
        touch_state = True
    if not touch.touched and touch_state:
        touch_state = False

@tannewt
Copy link
Member

tannewt commented Mar 11, 2024

Sounds like I didn't implement everything needed. I can't remember exactly how I tested it.

@RoxerRN
Copy link

RoxerRN commented Jan 17, 2025

Hi, a small bump here.

I have the same behavior with the example, I am unable to write to a file on my usb key. I can list all files but unable to write. After a while it crash the communication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants