diff --git a/micropython/drivers/storage/sdcard/sdcard.py b/micropython/drivers/storage/sdcard/sdcard.py index c9c991f59..1c1370c60 100644 --- a/micropython/drivers/storage/sdcard/sdcard.py +++ b/micropython/drivers/storage/sdcard/sdcard.py @@ -37,6 +37,20 @@ _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 @@ def init_card(self, baudrate): # 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 @@ def init_card(self, baudrate): # 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 @@ def init_card(self, baudrate): 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 @@ def init_card_v1(self): 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 @@ def readblocks(self, block_num, buf): 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 @@ def readblocks(self, block_num, buf): 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 @@ def readblocks(self, block_num, buf): 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): @@ -281,14 +295,14 @@ def writeblocks(self, block_num, buf): assert nblocks and not err, "Buffer length is invalid" if nblocks == 1: # CMD24: set write address for single block - if self.cmd(24, block_num * self.cdv, 0) != 0: + if self.cmd(24, block_num * self.cdv, 0x7F) != 0: raise OSError(5) # EIO # send the data self.write(_TOKEN_DATA, buf) else: # CMD25: set write address for first block - if self.cmd(25, block_num * self.cdv, 0) != 0: + if self.cmd(25, block_num * self.cdv, 0x7F) != 0: raise OSError(5) # EIO # send the data offset = 0