Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions micropython/drivers/storage/sdcard/sdcard.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,23 @@ def init_card(self, baudrate):

# get the number of sectors
# CMD9: response R2 (R1 byte + 16-byte block read)
csd = self.get_csd()
self.parse_csd(csd)

# CMD16: set block length to 512 bytes
if self.cmd(16, 512, 0) != 0:
raise OSError("can't set 512 block size")

# set to high data rate now that it's initialised
self.init_spi(baudrate)

def get_csd(self):
if self.cmd(9, 0, 0, 0, False) != 0:
raise OSError("no response from SD card")
csd = bytearray(16)
self.readinto(csd)

def parse_csd(self, csd):
if csd[0] & 0xC0 == 0x40: # CSD version 2.0
self.sectors = ((csd[7] << 16 | csd[8] << 8 | csd[9]) + 1) * 1024
elif csd[0] & 0xC0 == 0x00: # CSD version 1.0 (old, <=2GB)
Expand All @@ -106,14 +119,6 @@ def init_card(self, baudrate):
self.sectors = capacity // 512
else:
raise OSError("SD card CSD format not supported")
# print('sectors', self.sectors)

# CMD16: set block length to 512 bytes
if self.cmd(16, 512, 0) != 0:
raise OSError("can't set 512 block size")

# set to high data rate now that it's initialised
self.init_spi(baudrate)

def init_card_v1(self):
for i in range(_CMD_TIMEOUT):
Expand Down
44 changes: 44 additions & 0 deletions micropython/drivers/storage/sdcard/sdtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


def sdtest():
"""this test requires specific hardware, so is not run by CI"""
spi = machine.SPI(1)
spi.init() # Ensure right baudrate
sd = sdcard.SDCard(spi, machine.Pin.board.X21) # Compatible with PCB
Expand Down Expand Up @@ -61,3 +62,46 @@ def sdtest():
success = False
print()
print("Tests", "passed" if success else "failed")


class MockSDCard(sdcard.SDCard):
"""instantiates a sdcard object without talking to hardware"""

def __init__(self, spi, cs, baudrate=100_000):
super().__init__(spi, cs, baudrate=baudrate)

def init_card(self, baudrate):
"""yeah, this is where we're just going to skip the whole hardware initalization thing"""
self.baudrate = baudrate


def test_parse_csd(mockSD):
"""test the parse_csd function"""
csd_tests = [
{
"name": "64g card",
"sectors": 122191872,
"csd": bytearray(b"@\x0e\x002[Y\x00\x01\xd2\x1f\x7f\x80\n@\x00S"),
},
{
"name": "128g card",
"sectors": 244277248,
"csd": bytearray(b"@\x0e\x002[Y\x00\x03\xa3\xd7\x7f\x80\n@\x00A"),
},
]

for test in csd_tests:
mockSD.parse_csd(test["csd"])
sectors = mockSD.ioctl(4, None)
assert sectors == test["sectors"], "Failed to parse csd for test {}, {} != {}".format(
test["name"], sectors, test["sectors"]
)


def run_tests():
mockSD = MockSDCard(None, None)
test_parse_csd(mockSD)
print("OK")


run_tests()
Loading