33import vfs
44
55class SDCardManager :
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 ):
6+ def __init__ (self , mode = None , 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 = None , freq = 20000000 ):
88 self ._sdcard = None
99 self ._mode = None
1010
@@ -14,8 +14,8 @@ def __init__(self, mode='spi', spi_bus=None, cs_pin=None, cmd_pin=None, clk_pin=
1414 else :
1515 self ._mode = 'spi'
1616
17- # Allow explicit mode override
18- if mode in ('spi' , 'sdio' ):
17+ # Allow explicit mode override only if explicitly provided (not default)
18+ if mode is not None and mode in ('spi' , 'sdio' ):
1919 self ._mode = mode
2020
2121 print (f"SD card mode: { self ._mode .upper ()} " )
@@ -43,14 +43,41 @@ def _init_spi(self, spi_bus, cs_pin):
4343 print (" - Try: Hard reset ESP32, test with known-good SD card" )
4444
4545 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 ):
46+ slot = 1 , width = None , freq = 20000000 ):
4747 """Initialize SD card in SDIO mode."""
4848 # Validate required SDIO parameters
4949 if cmd_pin is None or clk_pin is None or d0_pin is None :
5050 print ("ERROR: SDIO mode requires cmd_pin, clk_pin, and d0_pin parameters" )
5151 print (" - Provide: init(mode='sdio', cmd_pin=X, clk_pin=Y, d0_pin=Z, ...)" )
5252 return
5353
54+ # Auto-detect SDIO width based on provided data pins
55+ # This happens BEFORE explicit width validation to allow user override
56+ if width is None :
57+ # Count how many data pins are provided
58+ data_pins_provided = sum ([
59+ d0_pin is not None ,
60+ d1_pin is not None ,
61+ d2_pin is not None ,
62+ d3_pin is not None
63+ ])
64+
65+ if data_pins_provided == 1 :
66+ # Only d0_pin provided: use 1-bit mode
67+ width = 1
68+ print ("INFO: Auto-detected SDIO width=1 (only d0_pin provided)" )
69+ elif data_pins_provided == 4 :
70+ # All four data pins provided: use 4-bit mode
71+ width = 4
72+ print ("INFO: Auto-detected SDIO width=4 (all four data pins provided)" )
73+ else :
74+ # Partial pins provided: this is an error
75+ print (f"ERROR: Invalid SDIO pin configuration - { data_pins_provided } data pins provided" )
76+ print (" - For 1-bit mode: provide only d0_pin" )
77+ print (" - For 4-bit mode: provide all four pins (d0_pin, d1_pin, d2_pin, d3_pin)" )
78+ print (" - Or explicitly specify width parameter to override auto-detection" )
79+ return
80+
5481 # Validate width parameter
5582 if width not in (1 , 4 ):
5683 print (f"ERROR: SDIO width must be 1 or 4, got { width } " )
@@ -61,14 +88,23 @@ def _init_sdio(self, cmd_pin, clk_pin, d0_pin, d1_pin=None, d2_pin=None, d3_pin=
6188 print (f"ERROR: SDIO slot must be 0 or 1, got { slot } " )
6289 return
6390
91+ # Validate that provided pins match the requested width
92+ if width == 4 :
93+ if d1_pin is None or d2_pin is None or d3_pin is None :
94+ print ("ERROR: SDIO 4-bit mode requires all four data pins (d0_pin, d1_pin, d2_pin, d3_pin)" )
95+ print (" - Provide all four data pins for 4-bit mode" )
96+ print (" - Or use 1-bit mode with only d0_pin" )
97+ return
98+ elif width == 1 :
99+ if d1_pin is not None or d2_pin is not None or d3_pin is not None :
100+ print ("ERROR: SDIO 1-bit mode should only have d0_pin, but extra pins were provided" )
101+ print (" - For 1-bit mode: provide only d0_pin" )
102+ print (" - For 4-bit mode: provide all four pins (d0_pin, d1_pin, d2_pin, d3_pin)" )
103+ return
104+
64105 try :
65106 # For 4-bit mode, all data pins are required
66107 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-
72108 self ._sdcard = machine .SDCard (
73109 slot = slot ,
74110 cmd = cmd_pin ,
@@ -199,18 +235,24 @@ def list(self, mount_point):
199235# --- Singleton pattern ---
200236_manager = None
201237
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 ):
238+ def init (mode = None , spi_bus = None , cs_pin = None , cmd_pin = None , clk_pin = None ,
239+ d0_pin = None , d1_pin = None , d2_pin = None , d3_pin = None , slot = 1 , width = None , freq = 20000000 ):
204240 """
205241 Initialize the global SD card manager.
206242
207243 SPI mode (default):
208244 init(spi_bus=machine.SPI(...), cs_pin=pin_number)
209245
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)
246+ SDIO mode with auto-detection:
247+ init(mode='sdio', cmd_pin=X, clk_pin=Y, d0_pin=Z, d1_pin=A, d2_pin=B, d3_pin=C, slot=1, freq=20000000)
248+
249+ SDIO width auto-detection:
250+ - If only d0_pin is provided: width is auto-set to 1 (1-bit mode)
251+ - If all four data pins (d0, d1, d2, d3) are provided: width is auto-set to 4 (4-bit mode)
252+ - If width parameter is explicitly provided: that value is used (overrides auto-detection)
253+ - If partial data pins are provided (e.g., only d0 and d1): raises an error
212254
213- Auto-detection:
255+ Auto-detection of mode :
214256 If SDIO pins are provided, SDIO mode is used automatically.
215257 """
216258 global _manager
0 commit comments