adafruit / Adafruit_CircuitPython_SD

SD card drivers for Adafruit CircuitPython
MIT License
37 stars 17 forks source link

strange behavior with tFT Featherwing and second SD Card #35

Closed jerryneedell closed 3 years ago

jerryneedell commented 4 years ago

I'm not sure this is really an issue with the library but I wanted to capture it and this seemed like a good place to start...

This was initially reported by another user via Discord but i have reproduced and expanded it.

The initial scenario is with a TFT Feather wing and Adalogger Featherwing attached to a feather_m4_express. It was discovered that if the there are SDCards inserted into both the TFT Featherwing and the Adalogger then when an attempt is made to access the Adalogger SDCard, it fails

code listings for sdmount_lib.py and sdmountd5_lib.py at the bottom of this post

Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 6.0.0-alpha.0-29-g111f7ddf6 on 2020-06-30; Adafruit Feather M4 Express with samd51j19
>>> import sdmount_lib
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sdmount_lib.py", line 9, in <module>
  File "adafruit_sdcard.py", line 116, in __init__
  File "adafruit_sdcard.py", line 177, in _init_card
  File "adafruit_sdcard.py", line 151, in _init_card
  File "adafruit_sdcard.py", line 210, in _init_card_v2
OSError: timeout waiting for v2 card
>>> 

but if the SDCard is removed from the TFT Card rate (which is never accessed) then the Adalogger Card is accessible


Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 6.0.0-alpha.0-29-g111f7ddf6 on 2020-06-30; Adafruit Feather M4 Express with samd51j19
>>> import sdmount_lib
SDcard on D11 mounted as /sd
>>> 

however -- just to confuse things if you then insert and access the TFT SDCard them ADLogger card now becomes available...


Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 6.0.0-alpha.0-29-g111f7ddf6 on 2020-06-30; Adafruit Feather M4 Express with samd51j19
>>> import sdmountd5_lib
SDCard on D5 mounted as /sd2
>>> import sdmount_lib
SDcard on D11 mounted as /sd
>>> 

both remain accessible until the next power cycle of the board. The Adaogger is still accessible through a Hard Reset but not after a power cycle

I tried reproducing this with the feather_m4_express, an Adalogger featherwing and an SDCard Breakout but I am unable to reproduce the problems. Both cards are accessible. No problems wit this configuration.

So, the issue appears to be dependent on the presence of the TFF featherwing.

For a third scenario, I used the feather_m4_express, TFT Featherwing and a SDCard breakout (replaced the Adalogger with the SDCard breakout) In this case, I cannot reproduce the initial issue - the SDCard in the breakout is accessible even if the TFT Card is in inserted BUT -- if I configure the TFT Display so it is active (echoing REPL), then I can no longer read from the breakout board -- it fails with a "No SD Card found" error UNTIL I power cycle only the Breakout board, leaving the TFT configured -- for one attempt after a power cycle of the Breakout board, I can read from it normally. Subsequent attempts fail with the "No SDCard found" error. I can still access the SDCard on the TFT. If I power cycle the whole system, I can repeatedly access both SDCards. (the TFT is inactive on power up)

My head hurts....

As noted, I am not convinced this is an issue with the Driver, but I'm not sure where to look or where else to post this. Suggestions welcome.

sdmount_lib.py -- mounts the Adalogger or SDCard Breakout

import adafruit_sdcard
import busio
import digitalio
import board
import storage
import sys
# Connect to the card and mount the filesystem.
cs = digitalio.DigitalInOut(board.D11)
sdcard = adafruit_sdcard.SDCard(board.SPI(), cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
sys.path.append("/sd")
sys.path.append("/sd/lib")
print("SDcard on D11 mounted as /sd")

sdmountd5_lib.py - Mounts the TFT Featherwing

import adafruit_sdcard
import busio
import digitalio
import board
import storage
import sys
# Connect to the card and mount the filesystem.
cs = digitalio.DigitalInOut(board.D5)
sdcard = adafruit_sdcard.SDCard(board.SPI(), cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd2")
sys.path.append("/sd2")
sys.path.append("/sd2/lib")
print("SDCard on D5 mounted as /sd2")
jepler commented 3 years ago

If there are other devices on the bus such as an SPI TFT, the SD card must always be initialized first. The main (but unofficial) reference I use for SD cards says this:

There is an important thing needs to be considered that the MMC/SDC is initially NOT the SPI device. Some bus activity to access another SPI device can cause a bus conflict due to an accidental response of the MMC/SDC. Therefore the MMC/SDC should be initialized to put it into the SPI mode prior to access any other device attached to the same SPI bus.

I don't think there's a way for adafruit_sdcard to detect when this rule has not been followed.