forked from MicroPythonOS/MicroPythonOS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsdcard.py
More file actions
157 lines (144 loc) · 7.09 KB
/
sdcard.py
File metadata and controls
157 lines (144 loc) · 7.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import os
import machine
import vfs
class SDCardManager:
def __init__(self, spi_bus, cs_pin):
self._sdcard = None
try:
self._sdcard = machine.SDCard(spi_bus=spi_bus, cs=cs_pin)
self._sdcard.info()
print("SD card initialized successfully")
except Exception as e:
print(f"ERROR: Failed to initialize SD card: {e}")
print(" - Possible causes: Invalid SPI configuration, SD card not inserted, faulty wiring, or firmware issue")
print(f" - Check: SPI pins for the SPI bus, card insertion, VCC (3.3V/5V), GND")
print(" - Try: Hard reset ESP32, test with known-good SD card")
def _try_mount(self, mount_point):
try:
os.mount(self._sdcard, mount_point)
print(f"SD card mounted successfully at {mount_point}")
return True
except OSError as e:
import errno
if e.errno == errno.EPERM: # EPERM is 1, meaning already mounted
print(f"Got mount error {e} which means already mounted.")
return True
else:
print(f"WARNING: Failed to mount SD card at {mount_point}: {e}")
print(" - Possible causes: Unformatted SD card (needs FAT32), corrupted filesystem, or card removed")
print(f" - Check: SD card format, ensure card is inserted")
print(" - Try: Format card on PC, or proceed to auto-format if enabled")
return False
def _format(self, mount_point):
try:
print(f"Attempting to format SD card for {mount_point}...")
try:
os.umount(mount_point)
print(f" - Unmounted {mount_point} (if it was mounted)")
except OSError:
print(f" - No prior mount found for {mount_point}, proceeding with format")
vfs.VfsFat.mkfs(self._sdcard)
print("SD card formatted successfully as FAT32")
return True
except OSError as e:
print(f"ERROR: Failed to format SD card: {e}")
print(" - Possible causes: SD card not inserted, write-protected, incompatible, or hardware error")
print(f" - Check: Card insertion, write-protect switch, verify wiring of SPI bus.")
print(" - Try: Test with another SD card, reformat on PC, ensure VCC/GND correct")
return False
def mount_with_optional_format(self, mount_point):
if not self._sdcard:
print(f"ERROR: No SD card object initialized for mounting at {mount_point}")
print(" - Possible causes: SD card initialization failed in __init__")
print(" - Check: Review initialization errors above, verify SPI setup and hardware")
print(" - Try: Hard reset, check SPI pins and SD card")
return False
if not self._try_mount(mount_point):
print(f"INFO: Initial mount failed at {mount_point}, attempting to format...")
if self._format(mount_point):
if not self._try_mount(mount_point):
print(f"ERROR: Failed to mount SD card at {mount_point} even after formatting")
print(" - Possible causes: Persistent hardware issue, incompatible SD card, or firmware bug")
print(f" - Check: Wiring of SPI bus and card type.")
print(" - Try: Hard reset, test with different SD card, reflash firmware")
return False
else:
print(f"ERROR: Could not format SD card for {mount_point} - mount aborted")
print(" - See format error details above for troubleshooting")
return False
try:
contents = os.listdir(mount_point)
print(f"SD card contents at {mount_point}: {contents}")
return True
except OSError as e:
print(f"WARNING: Could not list SD card contents at {mount_point}: {e}")
print(" - Possible causes: Filesystem corruption, card removed, or VFS cache issue")
print(f" - Check: Ensure card is inserted, verify mount with is_mounted('{mount_point}')")
print(" - Try: Unmount and remount, or reformat card")
return False
def is_mounted(self, mount_point):
try:
mounted = mount_point in os.listdir('/') and not os.mkdir(f'{mount_point}/_tmp_test')
if mounted:
print(f"SD card is mounted at {mount_point}")
try:
os.rmdir(f'{mount_point}/_tmp_test')
except:
pass
else:
print(f"SD card is not mounted at {mount_point}")
print(" - Possible causes: Never mounted, unmounted manually, or card removed")
print(f" - Try: Call mount_with_optional_format('{mount_point}')")
return mounted
except OSError as e:
print(f"WARNING: Failed to check mount status at {mount_point}: {e}")
print(" - Possible causes: Card removed, invalid mount point, or filesystem error")
print(f" - Check: Ensure {mount_point} exists and card is inserted")
print(" - Try: Remount or reinsert card")
return False
def list(self, mount_point):
try:
contents = os.listdir(mount_point)
print(f"SD card contents at {mount_point}: {contents}")
return contents
except OSError as e:
print(f"WARNING: Failed to list contents at {mount_point}: {e}")
print(" - Possible causes: SD card not mounted, removed, or corrupted filesystem")
print(f" - Check: Run is_mounted('{mount_point}'), ensure card is inserted")
print(" - Try: Remount with mount_with_optional_format('{mount_point}')")
return []
# --- Singleton pattern ---
_manager = None
def init(spi_bus, cs_pin):
"""Initialize the global SD card manager."""
global _manager
if _manager is None:
_manager = SDCardManager(spi_bus, cs_pin)
else:
print("WARNING: SDCardManager already initialized")
print(" - Use existing instance via get()")
return _manager
def get():
"""Get the global SD card manager instance."""
if _manager is None:
print("ERROR: SDCardManager not initialized")
print(" - Call init(spi_bus, cs_pin) first in lib/mpos/board/*.py")
return _manager
def mount(mount_point):
mgr = get()
if mgr is None:
print("ERROR: Cannot mount - SDCardManager not initialized")
print(" - Call init(spi_bus, cs_pin) first")
return False
return mgr.mount(mount_point)
def mount_with_optional_format(mount_point):
mgr = get()
if mgr is None:
print("ERROR: Cannot mount with format - SDCardManager not initialized")
print(" - Call init(spi_bus, cs_pin) first")
return False
success = mgr.mount_with_optional_format(mount_point)
if not success:
print(f"ERROR: mount_with_format('{mount_point}') failed")
print(" - See detailed errors above for mount or format issues")
return success