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>
pull/992/head
multicoder9 2025-03-29 22:51:52 +07:00 zatwierdzone przez GitHub
rodzic 96e17b65d1
commit 3ddee7c04f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
1 zmienionych plików z 25 dodań i 11 usunięć

Wyświetl plik

@ -37,6 +37,20 @@ _TOKEN_CMD25 = const(0xFC)
_TOKEN_STOP_TRAN = const(0xFD)
_TOKEN_DATA = const(0xFE)
## This function computes crc7 for SDcard commands
## It is not optimized, so do not call it where performance is critical
## You should usually be precomputing these values and hardcode them
#def crc7( cmd:bytes ):
# crc = 0
# for value in cmd:
# for i in range(8):
# crc <<= 1
# if (value&0x80)^(crc&0x80):
# crc ^= 0x09
# value <<= 1
# return ((crc<<1)|1)&0xFF
#def cmd_args_to_bytes( cmd:int, args:int ):
# return bytes( [cmd|0x40,(args>>24)&0xFF,(args>>16)&0xFF,(args>>8)&0xFF,args&0xFF] )
class SDCard:
def __init__(self, spi, cs, baudrate=1320000):
@ -92,7 +106,7 @@ class SDCard:
# get the number of sectors
# CMD9: response R2 (R1 byte + 16-byte block read)
if self.cmd(9, 0, 0, 0, False) != 0:
if self.cmd(9, 0, 0xAF, 0, False) != 0:
raise OSError("no response from SD card")
csd = bytearray(16)
self.readinto(csd)
@ -109,7 +123,7 @@ class SDCard:
# print('sectors', self.sectors)
# CMD16: set block length to 512 bytes
if self.cmd(16, 512, 0) != 0:
if self.cmd(16, 512, 0x15) != 0:
raise OSError("can't set 512 block size")
# set to high data rate now that it's initialised
@ -118,8 +132,8 @@ class SDCard:
def init_card_v1(self):
for i in range(_CMD_TIMEOUT):
time.sleep_ms(50)
self.cmd(55, 0, 0)
if self.cmd(41, 0, 0) == 0:
self.cmd(55, 0, 0x65)
if self.cmd(41, 0, 0xE5) == 0:
# SDSC card, uses byte addressing in read/write/erase commands
self.cdv = 512
# print("[SDCard] v1 card")
@ -129,10 +143,10 @@ class SDCard:
def init_card_v2(self):
for i in range(_CMD_TIMEOUT):
time.sleep_ms(50)
self.cmd(58, 0, 0, 4)
self.cmd(55, 0, 0)
if self.cmd(41, 0x40000000, 0) == 0:
self.cmd(58, 0, 0, -4) # 4-byte response, negative means keep the first byte
self.cmd(58, 0, 0xFD, 4)
self.cmd(55, 0, 0x65)
if self.cmd(41, 0x40000000, 0x77) == 0:
self.cmd(58, 0, 0xFD, -4) # 4-byte response, negative means keep the first byte
ocr = self.tokenbuf[0] # get first byte of response, which is OCR
if not ocr & 0x40:
# SDSC card, uses byte addressing in read/write/erase commands
@ -250,7 +264,7 @@ class SDCard:
assert nblocks and not len(buf) % 512, "Buffer length is invalid"
if nblocks == 1:
# CMD17: set read address for single block
if self.cmd(17, block_num * self.cdv, 0, release=False) != 0:
if self.cmd(17, block_num * self.cdv, 0x7F, release=False) != 0:
# release the card
self.cs(1)
raise OSError(5) # EIO
@ -258,7 +272,7 @@ class SDCard:
self.readinto(buf)
else:
# CMD18: set read address for multiple blocks
if self.cmd(18, block_num * self.cdv, 0, release=False) != 0:
if self.cmd(18, block_num * self.cdv, 0x7F, release=False) != 0:
# release the card
self.cs(1)
raise OSError(5) # EIO
@ -269,7 +283,7 @@ class SDCard:
self.readinto(mv[offset : offset + 512])
offset += 512
nblocks -= 1
if self.cmd(12, 0, 0xFF, skip1=True):
if self.cmd(12, 0, 0x61, skip1=True):
raise OSError(5) # EIO
def writeblocks(self, block_num, buf):