SDCard framework: add support for SDIO/SD/MMC mode

This commit is contained in:
Thomas Farstrike
2026-02-10 11:25:45 +01:00
parent b50c0d09d2
commit 67f01c3af2
2 changed files with 60 additions and 22 deletions
@@ -100,13 +100,9 @@ io0_pin.irq(trigger=machine.Pin.IRQ_FALLING, handler=io0_interrupt_handler)
# Initialize LVGL
lv.init()
# TODO: initialize SDIO (instead of SPI) SD card with:
# CMD = 2
# SCLK = 42
# D0 = 41
#import mpos.sdcard
#mpos.sdcard.init(spi_bus, cs_pin=14)
# Initialize SD card in SDIO mode
from mpos import sdcard
sdcard.init(cmd_pin=2,clk_pin=42,d0_pin=41)
# === AUDIO HARDWARE ===
# Note: MaTouch ESP32-S3 has no buzzer or I2S audio hardware
+57 -15
View File
@@ -3,8 +3,8 @@ import machine
import vfs
class SDCardManager:
def __init__(self, mode='spi', spi_bus=None, cs_pin=None, cmd_pin=None, clk_pin=None,
d0_pin=None, d1_pin=None, d2_pin=None, d3_pin=None, slot=1, width=4, freq=20000000):
def __init__(self, mode=None, spi_bus=None, cs_pin=None, cmd_pin=None, clk_pin=None,
d0_pin=None, d1_pin=None, d2_pin=None, d3_pin=None, slot=1, width=None, freq=20000000):
self._sdcard = None
self._mode = None
@@ -14,8 +14,8 @@ class SDCardManager:
else:
self._mode = 'spi'
# Allow explicit mode override
if mode in ('spi', 'sdio'):
# Allow explicit mode override only if explicitly provided (not default)
if mode is not None and mode in ('spi', 'sdio'):
self._mode = mode
print(f"SD card mode: {self._mode.upper()}")
@@ -43,7 +43,7 @@ class SDCardManager:
print(" - Try: Hard reset ESP32, test with known-good SD card")
def _init_sdio(self, cmd_pin, clk_pin, d0_pin, d1_pin=None, d2_pin=None, d3_pin=None,
slot=1, width=4, freq=20000000):
slot=1, width=None, freq=20000000):
"""Initialize SD card in SDIO mode."""
# Validate required SDIO parameters
if cmd_pin is None or clk_pin is None or d0_pin is None:
@@ -51,6 +51,33 @@ class SDCardManager:
print(" - Provide: init(mode='sdio', cmd_pin=X, clk_pin=Y, d0_pin=Z, ...)")
return
# Auto-detect SDIO width based on provided data pins
# This happens BEFORE explicit width validation to allow user override
if width is None:
# Count how many data pins are provided
data_pins_provided = sum([
d0_pin is not None,
d1_pin is not None,
d2_pin is not None,
d3_pin is not None
])
if data_pins_provided == 1:
# Only d0_pin provided: use 1-bit mode
width = 1
print("INFO: Auto-detected SDIO width=1 (only d0_pin provided)")
elif data_pins_provided == 4:
# All four data pins provided: use 4-bit mode
width = 4
print("INFO: Auto-detected SDIO width=4 (all four data pins provided)")
else:
# Partial pins provided: this is an error
print(f"ERROR: Invalid SDIO pin configuration - {data_pins_provided} data pins provided")
print(" - For 1-bit mode: provide only d0_pin")
print(" - For 4-bit mode: provide all four pins (d0_pin, d1_pin, d2_pin, d3_pin)")
print(" - Or explicitly specify width parameter to override auto-detection")
return
# Validate width parameter
if width not in (1, 4):
print(f"ERROR: SDIO width must be 1 or 4, got {width}")
@@ -61,14 +88,23 @@ class SDCardManager:
print(f"ERROR: SDIO slot must be 0 or 1, got {slot}")
return
# Validate that provided pins match the requested width
if width == 4:
if d1_pin is None or d2_pin is None or d3_pin is None:
print("ERROR: SDIO 4-bit mode requires all four data pins (d0_pin, d1_pin, d2_pin, d3_pin)")
print(" - Provide all four data pins for 4-bit mode")
print(" - Or use 1-bit mode with only d0_pin")
return
elif width == 1:
if d1_pin is not None or d2_pin is not None or d3_pin is not None:
print("ERROR: SDIO 1-bit mode should only have d0_pin, but extra pins were provided")
print(" - For 1-bit mode: provide only d0_pin")
print(" - For 4-bit mode: provide all four pins (d0_pin, d1_pin, d2_pin, d3_pin)")
return
try:
# For 4-bit mode, all data pins are required
if width == 4:
if d1_pin is None or d2_pin is None or d3_pin is None:
print("ERROR: SDIO 4-bit mode requires d0_pin, d1_pin, d2_pin, and d3_pin")
print(" - Provide all four data pins for 4-bit mode")
return
self._sdcard = machine.SDCard(
slot=slot,
cmd=cmd_pin,
@@ -199,18 +235,24 @@ class SDCardManager:
# --- Singleton pattern ---
_manager = None
def init(mode='spi', spi_bus=None, cs_pin=None, cmd_pin=None, clk_pin=None,
d0_pin=None, d1_pin=None, d2_pin=None, d3_pin=None, slot=1, width=4, freq=20000000):
def init(mode=None, spi_bus=None, cs_pin=None, cmd_pin=None, clk_pin=None,
d0_pin=None, d1_pin=None, d2_pin=None, d3_pin=None, slot=1, width=None, freq=20000000):
"""
Initialize the global SD card manager.
SPI mode (default):
init(spi_bus=machine.SPI(...), cs_pin=pin_number)
SDIO mode:
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)
SDIO mode with auto-detection:
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)
Auto-detection:
SDIO width auto-detection:
- If only d0_pin is provided: width is auto-set to 1 (1-bit mode)
- If all four data pins (d0, d1, d2, d3) are provided: width is auto-set to 4 (4-bit mode)
- If width parameter is explicitly provided: that value is used (overrides auto-detection)
- If partial data pins are provided (e.g., only d0 and d1): raises an error
Auto-detection of mode:
If SDIO pins are provided, SDIO mode is used automatically.
"""
global _manager