Skip to content

Commit b50c0d0

Browse files
SDCard framework: add support for SDIO/SD/MMC mode
1 parent 437fc7c commit b50c0d0

1 file changed

Lines changed: 125 additions & 10 deletions

File tree

internal_filesystem/lib/mpos/sdcard.py

Lines changed: 125 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,97 @@
33
import vfs
44

55
class SDCardManager:
6-
def __init__(self, spi_bus, cs_pin):
6+
def __init__(self, mode='spi', spi_bus=None, cs_pin=None, cmd_pin=None, clk_pin=None,
7+
d0_pin=None, d1_pin=None, d2_pin=None, d3_pin=None, slot=1, width=4, freq=20000000):
78
self._sdcard = None
9+
self._mode = None
10+
11+
# Auto-detect mode: if SDIO pins provided, use SDIO; otherwise use SPI
12+
if cmd_pin is not None or clk_pin is not None or d0_pin is not None:
13+
self._mode = 'sdio'
14+
else:
15+
self._mode = 'spi'
16+
17+
# Allow explicit mode override
18+
if mode in ('spi', 'sdio'):
19+
self._mode = mode
20+
21+
print(f"SD card mode: {self._mode.upper()}")
22+
23+
if self._mode == 'spi':
24+
self._init_spi(spi_bus, cs_pin)
25+
elif self._mode == 'sdio':
26+
self._init_sdio(cmd_pin, clk_pin, d0_pin, d1_pin, d2_pin, d3_pin, slot, width, freq)
27+
28+
def _init_spi(self, spi_bus, cs_pin):
29+
"""Initialize SD card in SPI mode."""
30+
if spi_bus is None or cs_pin is None:
31+
print("ERROR: SPI mode requires spi_bus and cs_pin parameters")
32+
print(" - Provide: init(spi_bus=machine.SPI(...), cs_pin=pin_number)")
33+
return
34+
835
try:
936
self._sdcard = machine.SDCard(spi_bus=spi_bus, cs=cs_pin)
1037
self._sdcard.info()
11-
print("SD card initialized successfully")
38+
print("SD card initialized successfully in SPI mode")
1239
except Exception as e:
13-
print(f"ERROR: Failed to initialize SD card: {e}")
40+
print(f"ERROR: Failed to initialize SD card in SPI mode: {e}")
1441
print(" - Possible causes: Invalid SPI configuration, SD card not inserted, faulty wiring, or firmware issue")
1542
print(f" - Check: SPI pins for the SPI bus, card insertion, VCC (3.3V/5V), GND")
1643
print(" - Try: Hard reset ESP32, test with known-good SD card")
44+
45+
def _init_sdio(self, cmd_pin, clk_pin, d0_pin, d1_pin=None, d2_pin=None, d3_pin=None,
46+
slot=1, width=4, freq=20000000):
47+
"""Initialize SD card in SDIO mode."""
48+
# Validate required SDIO parameters
49+
if cmd_pin is None or clk_pin is None or d0_pin is None:
50+
print("ERROR: SDIO mode requires cmd_pin, clk_pin, and d0_pin parameters")
51+
print(" - Provide: init(mode='sdio', cmd_pin=X, clk_pin=Y, d0_pin=Z, ...)")
52+
return
53+
54+
# Validate width parameter
55+
if width not in (1, 4):
56+
print(f"ERROR: SDIO width must be 1 or 4, got {width}")
57+
return
58+
59+
# Validate slot parameter
60+
if slot not in (0, 1):
61+
print(f"ERROR: SDIO slot must be 0 or 1, got {slot}")
62+
return
63+
64+
try:
65+
# For 4-bit mode, all data pins are required
66+
if width == 4:
67+
if d1_pin is None or d2_pin is None or d3_pin is None:
68+
print("ERROR: SDIO 4-bit mode requires d0_pin, d1_pin, d2_pin, and d3_pin")
69+
print(" - Provide all four data pins for 4-bit mode")
70+
return
71+
72+
self._sdcard = machine.SDCard(
73+
slot=slot,
74+
cmd=cmd_pin,
75+
clk=clk_pin,
76+
data_pins=(d0_pin,d1_pin,d2_pin,d3_pin,),
77+
width=width,
78+
freq=freq
79+
)
80+
else: # 1-bit mode
81+
self._sdcard = machine.SDCard(
82+
slot=slot,
83+
cmd=cmd_pin,
84+
clk=clk_pin,
85+
data_pins=(d0_pin,),
86+
width=width,
87+
freq=freq
88+
)
89+
90+
self._sdcard.info()
91+
print(f"SD card initialized successfully in SDIO mode (slot={slot}, width={width}-bit, freq={freq}Hz)")
92+
except Exception as e:
93+
print(f"ERROR: Failed to initialize SD card in SDIO mode: {e}")
94+
print(" - Possible causes: Invalid SDIO pin configuration, SD card not inserted, faulty wiring, or firmware issue")
95+
print(f" - Check: SDIO pins (CMD, CLK, D0-D3), card insertion, VCC (3.3V), GND")
96+
print(" - Try: Hard reset ESP32, verify pin assignments, test with known-good SD card")
1797

1898
def _try_mount(self, mount_point):
1999
try:
@@ -119,11 +199,36 @@ def list(self, mount_point):
119199
# --- Singleton pattern ---
120200
_manager = None
121201

122-
def init(spi_bus, cs_pin):
123-
"""Initialize the global SD card manager."""
202+
def init(mode='spi', spi_bus=None, cs_pin=None, cmd_pin=None, clk_pin=None,
203+
d0_pin=None, d1_pin=None, d2_pin=None, d3_pin=None, slot=1, width=4, freq=20000000):
204+
"""
205+
Initialize the global SD card manager.
206+
207+
SPI mode (default):
208+
init(spi_bus=machine.SPI(...), cs_pin=pin_number)
209+
210+
SDIO mode:
211+
init(mode='sdio', cmd_pin=X, clk_pin=Y, d0_pin=Z, d1_pin=A, d2_pin=B, d3_pin=C, slot=1, width=4, freq=20000000)
212+
213+
Auto-detection:
214+
If SDIO pins are provided, SDIO mode is used automatically.
215+
"""
124216
global _manager
125217
if _manager is None:
126-
_manager = SDCardManager(spi_bus, cs_pin)
218+
_manager = SDCardManager(
219+
mode=mode,
220+
spi_bus=spi_bus,
221+
cs_pin=cs_pin,
222+
cmd_pin=cmd_pin,
223+
clk_pin=clk_pin,
224+
d0_pin=d0_pin,
225+
d1_pin=d1_pin,
226+
d2_pin=d2_pin,
227+
d3_pin=d3_pin,
228+
slot=slot,
229+
width=width,
230+
freq=freq
231+
)
127232
else:
128233
print("WARNING: SDCardManager already initialized")
129234
print(" - Use existing instance via get()")
@@ -133,22 +238,32 @@ def get():
133238
"""Get the global SD card manager instance."""
134239
if _manager is None:
135240
print("ERROR: SDCardManager not initialized")
136-
print(" - Call init(spi_bus, cs_pin) first in lib/mpos/board/*.py")
241+
print(" - Call init() with appropriate parameters first in lib/mpos/board/*.py")
242+
print(" - SPI mode: init(spi_bus=machine.SPI(...), cs_pin=pin_number)")
243+
print(" - SDIO mode: init(mode='sdio', cmd_pin=X, clk_pin=Y, d0_pin=Z, ...)")
137244
return _manager
138245

246+
def get_mode():
247+
"""Get the current SD card mode ('spi' or 'sdio')."""
248+
mgr = get()
249+
if mgr is None:
250+
print("ERROR: Cannot get mode - SDCardManager not initialized")
251+
return None
252+
return mgr._mode
253+
139254
def mount(mount_point):
140255
mgr = get()
141256
if mgr is None:
142257
print("ERROR: Cannot mount - SDCardManager not initialized")
143-
print(" - Call init(spi_bus, cs_pin) first")
258+
print(" - Call init() with appropriate parameters first")
144259
return False
145-
return mgr.mount(mount_point)
260+
return mgr.mount_with_optional_format(mount_point)
146261

147262
def mount_with_optional_format(mount_point):
148263
mgr = get()
149264
if mgr is None:
150265
print("ERROR: Cannot mount with format - SDCardManager not initialized")
151-
print(" - Call init(spi_bus, cs_pin) first")
266+
print(" - Call init() with appropriate parameters first")
152267
return False
153268
success = mgr.mount_with_optional_format(mount_point)
154269
if not success:

0 commit comments

Comments
 (0)