Skip to content

Commit 60fbda4

Browse files
Improve SD Card support
1 parent d17c636 commit 60fbda4

File tree

1 file changed

+102
-27
lines changed

1 file changed

+102
-27
lines changed

internal_filesystem/lib/mpos/sdcard.py

Lines changed: 102 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,70 +8,145 @@ def __init__(self, spi_bus, cs_pin):
88
try:
99
self._sdcard = machine.SDCard(spi_bus=spi_bus, cs=cs_pin)
1010
self._sdcard.info()
11-
print("SD card initialized")
11+
print("SD card initialized successfully")
1212
except Exception as e:
1313
print(f"ERROR: Failed to initialize SD card: {e}")
14+
print(" - Possible causes: Invalid SPI configuration, SD card not inserted, faulty wiring, or firmware issue")
15+
print(f" - Check: SPI pins for the SPI bus, card insertion, VCC (3.3V/5V), GND")
16+
print(" - Try: Hard reset ESP32, test with known-good SD card")
1417

15-
def mount(self, mount_point):
16-
if not self._sdcard:
17-
return False
18+
def _try_mount(self, mount_point):
1819
try:
1920
os.mount(self._sdcard, mount_point)
20-
print(f"Mounted at {mount_point}")
21+
print(f"SD card mounted successfully at {mount_point}")
22+
return True
23+
except OSError as e:
24+
print(f"WARNING: Failed to mount SD card at {mount_point}: {e}")
25+
print(" - Possible causes: Unformatted SD card (needs FAT32), corrupted filesystem, or card removed")
26+
print(f" - Check: SD card format, ensure card is inserted")
27+
print(" - Try: Format card on PC, or proceed to auto-format if enabled")
28+
return False
29+
30+
def _format(self, mount_point):
31+
try:
32+
print(f"Attempting to format SD card for {mount_point}...")
33+
try:
34+
os.umount(mount_point)
35+
print(f" - Unmounted {mount_point} (if it was mounted)")
36+
except OSError:
37+
print(f" - No prior mount found for {mount_point}, proceeding with format")
38+
vfs.VfsFat.mkfs(self._sdcard)
39+
print("SD card formatted successfully as FAT32")
2140
return True
2241
except OSError as e:
23-
print(f"Mount failed: {e}")
42+
print(f"ERROR: Failed to format SD card: {e}")
43+
print(" - Possible causes: SD card not inserted, write-protected, incompatible, or hardware error")
44+
print(f" - Check: Card insertion, write-protect switch, verify wiring of SPI bus.")
45+
print(" - Try: Test with another SD card, reformat on PC, ensure VCC/GND correct")
2446
return False
2547

26-
def format_and_mount(self, mount_point):
48+
def mount_with_optional_format(self, mount_point):
2749
if not self._sdcard:
50+
print(f"ERROR: No SD card object initialized for mounting at {mount_point}")
51+
print(" - Possible causes: SD card initialization failed in __init__")
52+
print(" - Check: Review initialization errors above, verify SPI setup and hardware")
53+
print(" - Try: Hard reset, check SPI pins and SD card")
2854
return False
29-
print("Formatting SD card...")
30-
try:
31-
os.umount(mount_point)
32-
except:
33-
pass
55+
56+
if not self._try_mount(mount_point):
57+
print(f"INFO: Initial mount failed at {mount_point}, attempting to format...")
58+
if self._format(mount_point):
59+
if not self._try_mount(mount_point):
60+
print(f"ERROR: Failed to mount SD card at {mount_point} even after formatting")
61+
print(" - Possible causes: Persistent hardware issue, incompatible SD card, or firmware bug")
62+
print(f" - Check: Wiring of SPI bus and card type.")
63+
print(" - Try: Hard reset, test with different SD card, reflash firmware")
64+
return False
65+
else:
66+
print(f"ERROR: Could not format SD card for {mount_point} - mount aborted")
67+
print(" - See format error details above for troubleshooting")
68+
return False
69+
3470
try:
35-
vfs.VfsFat.mkfs(self._sdcard)
36-
print("Formatted")
37-
return self.mount(mount_point)
71+
contents = os.listdir(mount_point)
72+
print(f"SD card contents at {mount_point}: {contents}")
73+
return True
3874
except OSError as e:
39-
print(f"Format failed: {e}")
75+
print(f"WARNING: Could not list SD card contents at {mount_point}: {e}")
76+
print(" - Possible causes: Filesystem corruption, card removed, or VFS cache issue")
77+
print(f" - Check: Ensure card is inserted, verify mount with is_mounted('{mount_point}')")
78+
print(" - Try: Unmount and remount, or reformat card")
4079
return False
4180

4281
def is_mounted(self, mount_point):
4382
try:
44-
return mount_point in os.listdir('/') and os.path.ismount(mount_point)
45-
except:
83+
mounted = mount_point in os.listdir('/') and not os.mkdir(f'{mount_point}/_tmp_test')
84+
if mounted:
85+
print(f"SD card is mounted at {mount_point}")
86+
try:
87+
os.rmdir(f'{mount_point}/_tmp_test')
88+
except:
89+
pass
90+
else:
91+
print(f"SD card is not mounted at {mount_point}")
92+
print(" - Possible causes: Never mounted, unmounted manually, or card removed")
93+
print(f" - Try: Call mount_with_optional_format('{mount_point}')")
94+
return mounted
95+
except OSError as e:
96+
print(f"WARNING: Failed to check mount status at {mount_point}: {e}")
97+
print(" - Possible causes: Card removed, invalid mount point, or filesystem error")
98+
print(f" - Check: Ensure {mount_point} exists and card is inserted")
99+
print(" - Try: Remount or reinsert card")
46100
return False
47101

48102
def list(self, mount_point):
49103
try:
50-
return os.listdir(mount_point)
51-
except:
104+
contents = os.listdir(mount_point)
105+
print(f"SD card contents at {mount_point}: {contents}")
106+
return contents
107+
except OSError as e:
108+
print(f"WARNING: Failed to list contents at {mount_point}: {e}")
109+
print(" - Possible causes: SD card not mounted, removed, or corrupted filesystem")
110+
print(f" - Check: Run is_mounted('{mount_point}'), ensure card is inserted")
111+
print(" - Try: Remount with mount_with_optional_format('{mount_point}')")
52112
return []
53113

54-
# --- Global instance (singleton) ---
114+
# --- Singleton pattern ---
55115
_manager = None
56116

57117
def init(spi_bus, cs_pin):
58118
"""Initialize the global SD card manager."""
59119
global _manager
60120
if _manager is None:
61121
_manager = SDCardManager(spi_bus, cs_pin)
122+
else:
123+
print("WARNING: SDCardManager already initialized")
124+
print(" - Use existing instance via get()")
62125
return _manager
63126

64127
def get():
65128
"""Get the global SD card manager instance."""
129+
if _manager is None:
130+
print("ERROR: SDCardManager not initialized")
131+
print(" - Call init(spi_bus, cs_pin) first in boot.py or main.py")
66132
return _manager
67133

68-
# Optional: convenience functions
69134
def mount(mount_point):
70135
mgr = get()
71-
return mgr and mgr.mount(mount_point)
136+
if mgr is None:
137+
print("ERROR: Cannot mount - SDCardManager not initialized")
138+
print(" - Call init(spi_bus, cs_pin) first")
139+
return False
140+
return mgr.mount(mount_point)
72141

73-
def mount_with_format(mount_point):
142+
def mount_with_optional_format(mount_point):
74143
mgr = get()
75-
if mgr and not mgr.mount(mount_point):
76-
return mgr.format_and_mount(mount_point)
77-
return mgr and mgr.is_mounted(mount_point)
144+
if mgr is None:
145+
print("ERROR: Cannot mount with format - SDCardManager not initialized")
146+
print(" - Call init(spi_bus, cs_pin) first")
147+
return False
148+
success = mgr.mount_with_optional_format(mount_point)
149+
if not success:
150+
print(f"ERROR: mount_with_format('{mount_point}') failed")
151+
print(" - See detailed errors above for mount or format issues")
152+
return success

0 commit comments

Comments
 (0)