Skip to content

Commit 3ddee7c

Browse files
authored
Add CRC7 values for SDCard.cmd() function calls
Seems to be needed for some SDXC cards (SanDisk Ultra SDXC) Signed-off-by: multicoder9 <205438007+multicoder9@users.noreply.github.com>
1 parent 96e17b6 commit 3ddee7c

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

micropython/drivers/storage/sdcard/sdcard.py

+25-11
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,20 @@
3737
_TOKEN_STOP_TRAN = const(0xFD)
3838
_TOKEN_DATA = const(0xFE)
3939

40+
## This function computes crc7 for SDcard commands
41+
## It is not optimized, so do not call it where performance is critical
42+
## You should usually be precomputing these values and hardcode them
43+
#def crc7( cmd:bytes ):
44+
# crc = 0
45+
# for value in cmd:
46+
# for i in range(8):
47+
# crc <<= 1
48+
# if (value&0x80)^(crc&0x80):
49+
# crc ^= 0x09
50+
# value <<= 1
51+
# return ((crc<<1)|1)&0xFF
52+
#def cmd_args_to_bytes( cmd:int, args:int ):
53+
# return bytes( [cmd|0x40,(args>>24)&0xFF,(args>>16)&0xFF,(args>>8)&0xFF,args&0xFF] )
4054

4155
class SDCard:
4256
def __init__(self, spi, cs, baudrate=1320000):
@@ -92,7 +106,7 @@ def init_card(self, baudrate):
92106

93107
# get the number of sectors
94108
# CMD9: response R2 (R1 byte + 16-byte block read)
95-
if self.cmd(9, 0, 0, 0, False) != 0:
109+
if self.cmd(9, 0, 0xAF, 0, False) != 0:
96110
raise OSError("no response from SD card")
97111
csd = bytearray(16)
98112
self.readinto(csd)
@@ -109,7 +123,7 @@ def init_card(self, baudrate):
109123
# print('sectors', self.sectors)
110124

111125
# CMD16: set block length to 512 bytes
112-
if self.cmd(16, 512, 0) != 0:
126+
if self.cmd(16, 512, 0x15) != 0:
113127
raise OSError("can't set 512 block size")
114128

115129
# set to high data rate now that it's initialised
@@ -118,8 +132,8 @@ def init_card(self, baudrate):
118132
def init_card_v1(self):
119133
for i in range(_CMD_TIMEOUT):
120134
time.sleep_ms(50)
121-
self.cmd(55, 0, 0)
122-
if self.cmd(41, 0, 0) == 0:
135+
self.cmd(55, 0, 0x65)
136+
if self.cmd(41, 0, 0xE5) == 0:
123137
# SDSC card, uses byte addressing in read/write/erase commands
124138
self.cdv = 512
125139
# print("[SDCard] v1 card")
@@ -129,10 +143,10 @@ def init_card_v1(self):
129143
def init_card_v2(self):
130144
for i in range(_CMD_TIMEOUT):
131145
time.sleep_ms(50)
132-
self.cmd(58, 0, 0, 4)
133-
self.cmd(55, 0, 0)
134-
if self.cmd(41, 0x40000000, 0) == 0:
135-
self.cmd(58, 0, 0, -4) # 4-byte response, negative means keep the first byte
146+
self.cmd(58, 0, 0xFD, 4)
147+
self.cmd(55, 0, 0x65)
148+
if self.cmd(41, 0x40000000, 0x77) == 0:
149+
self.cmd(58, 0, 0xFD, -4) # 4-byte response, negative means keep the first byte
136150
ocr = self.tokenbuf[0] # get first byte of response, which is OCR
137151
if not ocr & 0x40:
138152
# SDSC card, uses byte addressing in read/write/erase commands
@@ -250,15 +264,15 @@ def readblocks(self, block_num, buf):
250264
assert nblocks and not len(buf) % 512, "Buffer length is invalid"
251265
if nblocks == 1:
252266
# CMD17: set read address for single block
253-
if self.cmd(17, block_num * self.cdv, 0, release=False) != 0:
267+
if self.cmd(17, block_num * self.cdv, 0x7F, release=False) != 0:
254268
# release the card
255269
self.cs(1)
256270
raise OSError(5) # EIO
257271
# receive the data and release card
258272
self.readinto(buf)
259273
else:
260274
# CMD18: set read address for multiple blocks
261-
if self.cmd(18, block_num * self.cdv, 0, release=False) != 0:
275+
if self.cmd(18, block_num * self.cdv, 0x7F, release=False) != 0:
262276
# release the card
263277
self.cs(1)
264278
raise OSError(5) # EIO
@@ -269,7 +283,7 @@ def readblocks(self, block_num, buf):
269283
self.readinto(mv[offset : offset + 512])
270284
offset += 512
271285
nblocks -= 1
272-
if self.cmd(12, 0, 0xFF, skip1=True):
286+
if self.cmd(12, 0, 0x61, skip1=True):
273287
raise OSError(5) # EIO
274288

275289
def writeblocks(self, block_num, buf):

0 commit comments

Comments
 (0)